先说说区间更新和单点更新的区别 主要的区别是搜索的过程 前者需要确定一个区间 后者就是一个点就好了
贴上两者代码
void updata(int i)//单点更新 { int l=stu[i].l; int r=stu[i].r; int mid=(l+r)/2;//二分咯 if(l==r&&r==x)//x为目标id 当左右节点相同的时候 就是找到这个数的时候 { stu[i].maxx=y; return; } if(l<=x&&x<=mid) updata(i*2);//向左找 else updata(i*2+1);//向右找 stu[i].maxx=max(stu[i*2].maxx,stu[i*2+1].maxx);//回溯的时候 更新max的数据 }
void update(int l,int r,int count)//x,y代表要更新的区间 //区间更新 { if(l>=x&&r<=y) { mapp[count].sum=z*mapp[count].len; mapp[count].flag=z; return; } pushdown(count); int mid=(l+r)/2; if(x<=mid) update(l,mid,count*2); if(y>=mid+1) update(mid+1,r,count*2+1); mapp[count].sum=mapp[count*2].sum+mapp[count*2+1].sum; }
在区间更新的时候 有的时候 我们不需要更新到底部 那么 这里引进一个延迟更新的概念 在搜索包含在我们需要的区间里面时 就可以返回了
那么在下次询问的时候 怎么保证底层的数据更新呢? 这里需要一个flag标记 如果当前的flag不为0的时候 向下更新 并更改当前的flag
比如在1-10标号的区间里面 我们要更新1-5的值
上代码
#include<iostream> #define maxn 111111 using namespace std; int n,q,x,y,z; struct stu { int l,r,sum,flag,len; }; stu mapp[maxn*4]; void build(int l,int r,int count) { mapp[count].l=l; mapp[count].r=r; mapp[count].flag=0; mapp[count].len=r-l+1; if(l==r) { mapp[count].sum=1; mapp[count].flag=1; return; } int mid=(l+r)/2; build(l,mid,count*2); build(mid+1,r,count*2+1); mapp[count].sum=mapp[count*2].sum+mapp[count*2+1].sum; } void pushdown(int count) { if(mapp[count].flag)//如果有标记 向下更新 { mapp[count*2].flag=mapp[count].flag; mapp[count*2+1].flag=mapp[count].flag; mapp[count*2].sum=mapp[count].flag*mapp[count*2].len; mapp[count*2+1].sum=mapp[count].flag*mapp[count*2+1].len; mapp[count].flag=0;//更新过一次 标记得消除 } }//向下更新的过程 void update(int l,int r,int count)//x,y代表要更新的区间 { if(l>=x&&r<=y) if(l==r) { mapp[count].sum=z*mapp[count].len; mapp[count].flag=z; return; } pushdown(count); int mid=(l+r)/2; if(x<=mid) update(l,mid,count*2); if(y>=mid+1) update(mid+1,r,count*2+1); mapp[count].sum=mapp[count*2].sum+mapp[count*2+1].sum; } int main() { cin.sync_with_stdio(false); int t; cin>>t; int casee=1; while(t--) { cin>>n; build(1,n,1); cin>>q; while(q--) { cin>>x>>y>>z; update(1,n,1); } cout<<"Case "<<casee++<<": The total value of the hook is "; cout<<mapp[1].sum<<"."<<endl; } return 0; }