思路:
分块,复杂度有点玄学,和普通分块不同的是在这个块被一次染色的时候暴力染整个块。
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using 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<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #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); //head const 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 ", query(l, r)); } } return 0; }