Write a piece of code to replace the following ancient code snippets.
long long data[250001];void A( int st, int nd ) { for( int i = st; i <= nd; i++ ) data[i] = data[i] + (i - st + 1);}void B( int st, int nd ) { for( int i = st; i <= nd; i++ ) data[i] = data[i] + (nd - i + 1);}void C( int st, int nd, int x ) { for( int i = st; i <= nd; i++ ) data[i] = x;}long long S( int st, int nd ) { long long res = 0; for( int i = st; i <= nd; i++ ) res += data[i]; return res;}
Solution: an obvious line segment tree.
Perform the following operations:
Operation A is to make the range St ~ Add 1 ~ to ND respectively ~ Nd-ST + 1, then we can plot the increment of this interval into the triangle above. We need to consider how to save this incremental triangle to the domain of the online segment tree for query.
We divide the triangle into two parts: the left and the right sides are still triangles, and the right side is a triangle and a rectangle (shadow part). Obviously, we only need to open another add field, save this rectangle increment in the add field, so we have completed the task of dividing the increment triangle into left and right subtree.
Operation B is to reverse the triangle of Operation A. The idea is the same as above.
Operate C .. This is not explained.
So it becomes a line segment tree that increases or decreases and is modified.
Then there are some details of the Code. I knocked for an hour, adjusted for 2 hours, orz
I can only run 818 ms, worship the great god of 48 8 ms.
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;typedef long long lld;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define ls (rt<<1)#define rs (rt<<1|1)const int MAXN = 250001;int cover[MAXN<<2];int opa[MAXN<<2],opb[MAXN<<2];lld sum[MAXN<<2];lld add[MAXN<<2];lld x;lld cal(int a, int b) {return (lld) (b-a+2) * (b-a+1) / 2;}void PRINT(int l, int r,int rt) { printf("************************\n"); printf("rt = %d\n", rt); printf("l = %d, r = %d\n", l, r); printf("sum = %lld\n", sum[rt]); printf("opa = %d\n", opa[rt]); printf("opb = %d\n", opb[rt]); printf("add = %lld\n", add[rt]); printf("cover = %d\n", cover[rt]); printf("*******************************\n\n");}void pushdown(int l, int r, int rt) { // PRINT(l,r,rt);int m = (l+r)>>1;if(cover[rt] == 1) {add[ls] = add[rs] = 0;opa[ls] = opa[rs] = opb[ls] = opb[rs] = 0;sum[ls] = sum[rs] = 0;cover[ls] = cover[rs] = cover[rt];cover[rt] = 0;}add[ls] += add[rt];add[rs] += add[rt];sum[ls] += (lld)(m-l+1)*add[rt];sum[rs] += (lld)(r-m)*add[rt];add[rt] = 0;opa[ls] += opa[rt];opa[rs] += opa[rt];opb[ls] += opb[rt];opb[rs] += opb[rt];sum[rs] += (lld)(m-l+1)*(r-m)*opa[rt];add[rs] += (lld)(m-l+1)*opa[rt];sum[rs] += (lld)(opa[rt]+opb[rt]) * cal(m+1,r);sum[ls] += (lld)(r-m)*(m-l+1)*opb[rt];add[ls] += (lld)(r-m)*opb[rt];sum[ls] += (lld)(opa[rt]+opb[rt]) * cal(l,m);opa[rt] = opb[rt] = 0;//PRINT(l,m,ls);//PRINT(m+1,r,rs);}void pushup(int l, int r, int rt) {int m = (l+r)>>1;sum[rt] = sum[ls] + sum[rs];}void update(int L, int R, char op, int l, int r, int rt) {if(L<=l && r<=R) { // PRINT(l,r,rt);if(op == 'A') {sum[rt] += (lld)(l-L)*(r-l+1); // printf("sum = %lld\n", sum[rt]);sum[rt] += cal(l,r);//printf("sum = %lld\n", sum[rt]);add[rt] += (lld)(l-L);opa[rt] ++;}else if(op == 'B') {sum[rt] += (lld)(R-r)*(r-l+1);sum[rt] += cal(l,r);add[rt] += (lld)(R-r);opb[rt] ++;}else {sum[rt] = x*(r-l+1);cover[rt] = 1;opa[rt] = opb[rt] = 0;add[rt] = x;}//PRINT(l,r,rt);//printf("l = %d, r = %d\n", l, r);//printf("sum = %lld,opa = %d,opb = %d,add = %lld,cover = %d\n",sum[rt],opa[rt],opb[rt],add[rt],cover[rt]);return ;}int m = (l+r)>>1;pushdown(l,r,rt);if(L<=m) update(L,R,op,lson);if(R> m) update(L,R,op,rson);pushup(l,r,rt);}lld query(int L, int R, int l, int r, int rt) {if(L<=l && r<=R) {return sum[rt];}int m = (l+r)>>1;pushdown(l,r,rt);lld ret = 0;if(L<=m) ret += query(L,R,lson);//printf("ret = %d\n", ret);if(R> m) ret += query(L,R,rson);//printf("ret = %d\n", ret);//PRINT(l,r,rt);return ret;}void build(int rt) {sum[rt] = add[rt] = 0;cover[rt] = 1;opa[rt] = opb[rt] = 0;}int main() {int q;int N = 250000;char s[2];int a,b;while(~scanf("%d", &q)) {build(1);while(q--) {scanf("%s%d%d", s, &a, &b);if(s[0] == 'S') {printf("%lld\n", query(a,b,1,N,1));}else {if(s[0] == 'C') scanf("%lld", &x);update(a,b,s[0],1,N,1);}}}return 0;}