zhw大神线段树姿势
for (i=131072; i<262144; i++) tree[i][0]=tree[i][1]=i; for (i=131071; i>=1; i--) tree[i][0]=tree[i+i][0], tree[i][1]=tree[i+i+1][1]; void Down(int x) { tree[x+x][2]+=tree[x][2]; tree[x+x+1][2]+=tree[x][2]; tree[x+x][3]+=tree[x][2]* (tree[x+x][1]-tree[x+x][0]+1); tree[x+x+1][3]+=tree[x][2]* (tree[x+x+1][1]-tree[x+x+1][0]+1); tree[x][2]=0; } int work(int root,int l,int r,int k) { if (tree[root][0]==l && tree[root][1]==r) { tree[root][2]+=k; tree[root][3]+=k*(r-l+1); return 0; } tree[root][3]+=k*(r-l+1); //Down(root); int mid=(tree[root][0]+tree[root][1])/2; if (l<=mid) work(root+root,l,min(mid,r),k); if (r>mid) work(root+root+1,max(mid+1,l),r,k); // tree[root][3]=tree[root+root][3]+tree[root+root+1][3]; return; } int work2(int root,int l,int r) { if (tree[root][0]==l && tree[root][1]==r) return tree[root][3]; Down(root); int mid=(tree[root][0]+tree[root][1])/2; int p=0,q=0; if (l<=mid) p=work2(root+root,l,min(mid,r)); if (r>mid) q=work2(root+root+1,max(mid+1,l),r); return p+q; } while (Q--) { cin>>A; if (A==1) { cin>>x>>y>>z; work(1,x+131071,y+131071,z); } if (A==2) { cin>>x>>y; cout<<work2(1,x+131071,y+131071); } } tree[i][0] 表示编号最小的叶子 tree[i][1] 编号最大的叶子 tree[i][2] 以i为根,所有叶子一次性全部加的, 总共加了多少。 tree[i][3] 以i为根,所有叶子的权值之和是多少
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。