思路:
分块,复杂度有点玄学,和普通分块不同的是在这个块被一次染色的时候暴力染整个块。
代码:
#pragma GCC optimize(2)#pragma GCC optimize(3)#pragma GCC optimize(4)#includeusing namespace std;#define fi first#define se second#define pi acos(-1.0)#define LL long long//#define mp make_pair#define pb push_back#define ls rt<<1, l, m#define rs rt<<1|1, m+1, r#define ULL unsigned LL#define pll pair #define pii pair #define piii pair #define mem(a, b) memset(a, b, sizeof(a))#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);//headconst int N = 1e5 + 5, M = 410;int a[N], lazy[M], bl[N], blo, n;LL v[N], bv[M], sm[M];void push_down(int x) { for (int i = (x-1)*blo + 1; i <= min(x*blo, n); i++) a[i] = lazy[x]; lazy[x] = 0;}void first_color(int x, int value) { for (int i = (x-1)*blo + 1; i <= min(x*blo, n); i++) v[i] += abs(value - a[i]), sm[x] += abs(value - a[i]), a[i] = value;}void update(int l, int r, int x) { if(bl[l] == bl[r]) { if(lazy[bl[l]]) push_down(bl[l]); for (int i = l; i <= r; i++) v[i] += abs(a[i] - x), sm[bl[i]] += abs(a[i] - x), a[i] = x; return ; } else { if(lazy[bl[l]]) push_down(bl[l]); for (int i = l; i <= bl[l]*blo; i++) { sm[bl[i]] += abs(a[i] - x); v[i] += abs(a[i] - x); a[i] = x; } for (int i = bl[l]+1; i <= bl[r]-1; i++) { if(lazy[i]) { bv[i] += abs(x - lazy[i]); sm[i] += 1LL * blo * abs(x - lazy[i]); lazy[i] = x; } else { first_color(i, x); lazy[i] = x; } } if(lazy[bl[r]]) push_down(bl[r]); for (int i = (bl[r]-1)*blo + 1; i <= r; i++) { sm[bl[i]] += abs(a[i] - x); v[i] += abs(a[i] - x); a[i] = x; } }}LL query(int l, int r) { LL ans = 0; if(bl[l] == bl[r]){ for (int i = l; i <= r; i++) { ans += v[i] + bv[bl[i]]; } return ans; } for (int i = l; i <= bl[l]*blo; i++) { ans += v[i] + bv[bl[i]]; } for (int i = bl[l]+1; i <= bl[r]-1; i++) { ans += sm[i]; } for (int i = (bl[r]-1)*blo+1; i <= r; i++) { ans += v[i] + bv[bl[i]]; } return ans;}int main() { int m, ty, l, r, x; scanf("%d %d", &n, &m); blo = sqrt(n); for (int i = 1; i <= n; i++) { bl[i] = (i-1)/blo + 1; a[i] = i; v[i] = 0; } while(m--) { scanf("%d", &ty); if(ty == 1) { scanf("%d %d %d", &l, &r, &x); update(l, r, x); } else { scanf("%d %d", &l, &r); printf("%lld\n", query(l, r)); } } return 0;}