Source: Light OJ 1411 Rip Van Winkle ' s Code
Test instructions: 3 operation 1 kinds of query to find the interval and each time can be a period from left to right plus three-way, ... or right-to-left plus ... 3,2,1 or set the number of a range to V
Idea: I was adding 6 domains
Add is the interval in which each number is added with the add add is so come on with 123456 ... This arithmetic progression may be divided into 2 intervals so I divide 123 and 1232 to the right arithmetic progression each number should also be added 3 so the right interval add plus 3
V is that this interval is set to V he has the highest priority.
B is the number of incremental arithmetic progression that represent this interval.
C is the number of descending arithmetic progression that represent this interval.
Sum is the interval and
F for true description to be executed C because V can be positive and negative or it can be 0
#include <cstdio> #include <cstring> #include <algorithm>using namespace std;const int maxn = 250010; typedef long LONG ll;struct node{ll sum, add, V, B, C; bool F;} A[maxn<<2];void Build (int l, int r, int rt) {a[rt].sum = 0;a[rt].add = 0;a[rt].b = 0;a[rt].c = 0;A[RT].F = False;if (l = = r) Return;int m = (L + R) >> 1;build (L, M, rt<<1); Build (M+1, R, rt<<1|1);} void Pushdown (int rt, int l, int r) {ll k = (ll) (r-l+1);//printf ("%d%d%lld\n", L, R, A[RT].V); if (A[RT].F) {a[rt<<1]. sum = (ll) a[rt].v* (K (k>>1)), A[rt<<1|1].sum = (ll) a[rt].v* (k>>1); a[rt<<1].v = a[rt<<1| 1].V = A[RT].V;A[RT<<1].F = A[RT<<1|1].F = TRUE;A[RT].F = false;a[rt<<1].b = a[rt<<1|1].b = 0;a[rt <<1].C = a[rt<<1|1].c = 0;a[rt<<1].add = A[rt<<1|1].add = 0;} LL S1 = (K (k>>1)); ll s2 = (k>>1); if (a[rt].b) {a[rt<<1].sum + = (ll) a[rt].b* (1+s1) *s1/2;a[rt<<1|1].sum + = (ll) a[rt].b* (1 +S2) *s2/2+ (LL) s2*s1*a[rt].b;a[rt<<1].b + = a[rt].b;a[rt<<1|1].b + A[rt].b;a[rt<<1|1].add + = (LL) s1*a[rt].b;a[rt].b = 0;} if (a[rt].c) {a[rt<<1].sum + = (ll) a[rt].c* (1+S1) *s1/2+ (ll) S2*s1*a[rt].c;a[rt<<1|1].sum + = (ll) a[rt].c* (1 +S2) *s2/2;a[rt<<1].c + = a[rt].c;a[rt<<1|1].c + A[rt].c;a[rt<<1].add + = (LL) s2*a[rt].c;a[rt].c = 0;} if (a[rt].add) {a[rt<<1].sum + = (ll) a[rt].add* (K (k>>1)); A[rt<<1|1].sum + = (ll) a[rt].add* (k> >1); A[rt<<1].add + = A[rt].add;a[rt<<1|1].add + = A[rt].add; A[rt].add = 0;}} void update (int x, int y, int l, int r, int RT, LL Add, ll V, char c) {//puts ("we"), if (L = = x && r = = y) {if (c = = ' A ') {/*if (a[rt].f) {a[rt].sum = (LL) (r-l+1) *v;//a[rt].f = false;} */a[rt].sum + = (ll) (r-l+1) * (r-l+1+1)/2;a[rt].b++;a[rt].sum + = (ll) add* (r-l+1); A[rt].add + = add;//printf ("%d%d%d%lld\ N ", L, R, A[rt].b, A[rt].sum);} else if (c = = ' B ') {/*if (a[rt].f) {a[rt].sum = (LL) (r-l+1) *v;//a[rt].f = false;} */a[rt].sum + = (LL) (r-l+1) * (r-l+1+1)/2;a[rt].c++;a[rt].sum + = (LL) add* (r-l+1); A[rt].add + = add;} else if (c = = ' C ') {a[rt].f = True;a[rt].add = 0;a[rt].sum = (LL) (r-l+1) *v;a[rt].b = 0;a[rt].c = 0;A[RT].V = v;} return;} int m = (L + R) >> 1;pushdown (RT, L, R), if (y <= m) {update (x, Y, L, M, rt<<1, add, V, c);} else if (x > m) {update (x, Y, m+1, R, Rt<<1|1, add, V, c);} Else{if (c = = ' A ') {update (x, M, L, M, rt<<1, add, V, c); Update (m+1, Y, m+1, R, Rt<<1|1, Add+ (m-x+1), V, c);} else if (c = = ' B ') {update (x, M, L, M, Rt<<1, add+ (y-m), V, c); Update (m+1, Y, m+1, R, Rt<<1|1, add, V, c);} else if (c = = ' C ') {//puts ("as"); Update (x, M, L, M, rt<<1, add, V, c); Update (m+1, Y, m+1, R, Rt<<1|1, add, V, c) ;}} A[rt].sum = A[rt<<1].sum + a[rt<<1|1].sum;} LL query (int x, int y, int l, int r, int rt) {if (x = = L && y = = r) {//printf ("**%d%d%lld\n", L, R, A[rt].sum); Retu RN A[rt].sum;} Pushdown (RT, L, R); int m = (L + r) >> 1; LL ans = 0;if (y <= m) ans + = query (x, Y, L, M, rt<<1), else if (x > m) ans + = query (x, Y, m+1, R, rt<<1|1); Elseans = query (x, M, L, M, rt<<1) + query (m+1, Y, m+1, R, rt<<1|1); a[rt].sum = A[rt<<1].sum + A[rt<<1|1].sum;return ans;} int main () {int cas = 1;int t;scanf ("%d", &t), while (t--) {int n = 250000;int q;scanf ("%d", &q);p rintf ("Case%d:\n", cas++); Build (1, N, 1), while (q--) {char s[10];scanf ("%s", s), if (s[0] = = ' A ') {int x, y;scanf ("%d%d", &x, &y); update (x, Y, 1, N, 1, 0, 0, ' A ');} else if (s[0] = = ' B ') {int x, y;scanf ("%d%d", &x, &y), update (x, y, 1, N, 1, 0, 0, ' B ');} else if (s[0] = = ' C ') {int x, y; LL w;scanf ("%d%d%lld", &x, &y, &w); update (x, y, 1, N, 1, 0, W, ' C ');} Else{int x, y;scanf ("%d%d", &x, &y);p rintf ("%lld\n", query (x, y, 1, N, 1));}}} return 0;} /*10B 1 4 A 1 4S 2 2B 1 3C 1 4 1 B 1 4C 3 3 3 a 2 3S 2 3B 3 3*/