标签:ISE style using 状态更新 数加 递归 ++ code amp
#include<bits/stdc++.h> using namespace std; int a,b,ans,n,m,x,y; //点-结构体 struct node { int l,r,w,f; }tree[400001]; //建树 左孩子结点为2*k 右孩子为2k+1 void build(int l,int r,int k) { tree[k].l=l; tree[k].r=r; if(tree[k].l==tree[k].r)//叶子结点 { scanf("%d",&tree[k].w); return; } int mid=(l+r)/2; bulid(l,mid,k*2); //左孩子 build(mid+1,r,k*2+1);//右孩子 tree[k].w=tree[k*2].w+tree[k*2+1].w;//状态合并,w为两个孩子w之和 } //标记下传 //f 每个子节点要加的值 void down(int k) { tree[k*2].f+=tree[k].f; tree[k*2+1].f+=tree[k].f; tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1); tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1); tree[k].f=0; } //单点查询 待查询点位置为x 初始一般k=1 void askp(int k) { if(tree[k].l==tree[k].r)//当前结点的左右端点相等,即是叶子节点(最终答案) { ans=tree[k].w; return; } if(tree[k].f)down(k); int mid=(tree[k].l+tree[k].r)/2; if(x<=mid)askp(k*2);//目标位置比中点靠左,则递归左孩子 else askp(k*2+1); //靠右,则递归右孩子 } //单点修改 比如:对第x个数加上y //revise 修改 void rep(int k) { if(tree[k].l==tree[k].r)//找到目标位置 { tree[k].w+=y; return; } if(tree[k].f)down(k); int mid=(tree[k].l+tree[k].r)/2; if(x<=mid)add(k*2); else add(k*2+1); tree[k].w=tree[k*2].w+tree[k*2+1].w;//所有包含结点k的结点状态更新 } //区间查询 区间[a,b]之和 //a<=mid,即查询区间全在当前区间的左子区间,递归左孩子 //b>mid。即查询区间全在当前区间的右子区间,递归右孩子 void askin(int k) { if(tree[k].l>=a&&tree[k].r<=b) { ans+=tree[k].w; return; } if(tree[k].f)down(k); int mid=(tree[k].l+tree[k].r)/2; if(a<=mid)askin(k*2); if(b>mid)askin(k*2+1); } //区间修改,即修改一段连续区间的值 void rein(int k) { if(tree[k].l>=a&&tree[k].r<=b) { tree[k].w+=(tree[k].r-tree[k].l+1)*y; tree[k].f+=y; return; } if(tree[k].f)down(k); int mid=(tree[k].l+tree[k].r)/2; if(a<=mid)rein(k*2); if(b>mid)rein(k*2+1); tree[k].w=tree[k*2].w+tree[k*2+1].w; } int main() { scanf("%d",&n);//n个节点 build(n,1,1);//建树 scanf("%d",&m);//m种操作 for(int i=1;i<=m;i++) { scanf("%d",&p); ans=0; if(p==1) { scanf("%d",&x); ap(1);//单点查询,输出第x个数 printf("%d",ans); } else if(p==2) { scanf("%d%d",&x,&y); rep(1);//单点修改 } else if(p==3) { scanf("%d%d",&a,&b);//区间查询 askin(1); printf("%d\n",ans); } else { scanf("%d%d%d",&a,&b,&y);//区间修改 rein(1); } } return 0; }
标签:ISE style using 状态更新 数加 递归 ++ code amp
原文地址:https://www.cnblogs.com/kannyi/p/9792671.html