Just a Hook(成段更新,节点求和,lazy思想)

题目的大意是:

一开始有n个钩子,然后他们的价值全是1。

然后有Q次操作,然后每次有三个数x,y,z;你可以改变从x到y的区间的钩子的值为z。

然后最后一个询问,要你输出n个钩子的总价值是多少。

这里我首次接触到了lazy思想,实际上就是给完全包含当前区间的那个区间标记一下,然后不继续往下面更新,直到下次继续遇到这个区间并且需要继续往下面更新才把当前的lazy标记往下去更新。并且也不要忘记pushup更新操作。

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;#define maxn 111111int a[maxn];struct node{int l,r;int x;int add,flag;}tree[maxn*4];int ans=0;void pushup(int v){int temp=v<<1;tree[v].x=tree[temp].x+tree[temp+1].x;}void pushdown(int v,int x){int temp=v<<1;tree[temp].x=x*(tree[temp].r-tree[temp].l+1);tree[temp+1].x=x*(tree[temp+1].r-tree[temp+1].l+1);tree[v].add=0;}void build(int l,int r,int v){tree[v].l=l;tree[v].r=r;tree[v].x=1;tree[v].add=0;tree[v].flag=0;if(l==r) return;int mid=(tree[v].l+tree[v].r)>>1;int temp=v<<1;build(l,mid,temp);build(mid+1,r,temp+1);pushup(v);}void update(int l,int r,int v,int x){if(l==tree[v].l&&r==tree[v].r){tree[v].x=x*(r-l+1);tree[v].flag=1;tree[v].add=x;return;}int mid=(tree[v].l+tree[v].r)>>1;int temp=v<<1;if(tree[v].flag==1){tree[v].flag=0;update(tree[v].l,mid,temp,tree[v].add);update(mid+1,tree[v].r,temp+1,tree[v].add);tree[v].add=0;}if(r<=mid) update(l,r,temp,x);else if(l>mid) update(l,r,temp+1,x);else{update(l,mid,temp,x);update(mid+1,r,temp+1,x);}pushup(v);}int main(){int T,n,x,y,z,Q;while(~scanf("%d",&T)){int j=1;while(T–){memset(a,0,sizeof(a));scanf("%d",&n);build(0,n-1,1);#if 1scanf("%d",&Q);while(Q–){scanf("%d%d%d",&x,&y,&z);x–; y–;update(x,y,1,z);}ans=tree[1].x;printf("Case %d: The total value of the hook is %d.\n",j++,ans);#endif}}}

,一个人负心,或许是因为他的记忆力不好。

Just a Hook(成段更新,节点求和,lazy思想)

相关文章:

你感兴趣的文章:

标签云: