不知道WA哪了。。。

0
0

include

include

include

using namespace std; const int N = 100005;

define ls (rt<<1)

define rs (rt<<1|1)

define mid (l+r>>1)

int value[N]; struct Node{ int l,r,sum,mark,add,set; }node[N<<2]; void pushUp(int rt){ node[rt].sum = node[ls].sum + node[rs].sum; } void pushDown(int rt){ if(node[rt].mark == 0){ int add = node[rt].add; node[ls].mark = 0,node[ls].add += add; node[rs].mark = 0,node[rs].add += add; node[rt].mark = -1,node[rt].add = node[rt].set = 0; node[ls].sum += (node[ls].r-node[ls].l+1)*add; node[rs].sum += (node[rs].r-node[rs].l+1)*add; } else if(node[rt].mark == 1){ int set = node[rt].set; node[ls].mark = 1,node[ls].set = set,node[ls].add = 0; node[rs].mark = 1,node[rs].set = set,node[rs].add = 0; node[rt].mark = -1,node[rt].add = node[rt].set = 0; node[ls].sum = (node[ls].r-node[ls].l+1)*set; node[rs].sum = (node[rs].r-node[rs].l+1)*set; } } void build(int rt,int l,int r){ node[rt].l = l,node[rt].r = r; node[rt].mark = -1,node[rt].add = node[rt].set = 0; if(l == r){ node[rt].sum = value[l]; return; } build(ls,l,mid); build(rs,mid+1,r); pushUp(rt); } void update(int rt,int L,int R,int mark,int val){ int l = node[rt].l,r = node[rt].r; if(L <= l && r <= R){ node[rt].mark = mark; if(mark == 0){ node[rt].sum += (r-l+1)*val; node[rt].add += val; } else{ node[rt].sum = (r-l+1)*val; node[rt].add = 0,node[rt].set = val; } return; } pushDown(rt); if(L <= mid) update(ls,L,R,mark,val); if(R > mid) update(rs,L,R,mark,val); pushUp(rt); } int query(int rt,int L,int R){ int l = node[rt].l,r = node[rt].r,res = 0; if(L <= l && r <= R) return node[rt].sum; pushDown(rt); if(L <= mid) res += query(ls,L,R); if(R > mid) res += query(rs,L,R); return res; } int main(){ int n,m,L,R,t,v,rt = 1; scanf("%d %d",&n,&m); for(int i = 0;i <= n;i++) scanf("%d",&value[i]); build(rt,0,n); for(int i = 0;i < m;i++){ scanf("%d %d %d %d",&t,&L,&R,&v); update(rt,L,R,t,v); printf("%d\n", query(rt,0,n)); } return 0; }

  • 大神给我一份代码吧,我不会构造这样的线段树,

  • 添加评论
  • reply

1 answer(s)

1

已找到原因

  • 请问是什么原因 我感觉和你遇到问题一样a

  • 1、一开始认为一个节点在一次更新后必定只剩下一个标记,其实不然,可能剩下两个标记,比如 set[0,10],add[0,6]之后,节点[0,5]就带有set和add标记; 2、还有一点就是一个节点若同时存在add,set标记,因为set标记会覆盖add标记,那么一定是先set后add,所以讲标记向下传递时,一定是先处理set,再处理add,这点一定要注意。

  • 大神啊,谢谢了 我通过了

  • 顶一个,我也是这个原因

  • 添加评论
  • reply

write answer 切换为英文 切换为中文


转发分享