hdu1698线段树区间更新
题目链接:https://vjudge.net/contest/66989#problem/E
坑爹的线段树照着上一个线段树更新写的,结果发现有一个地方就是不对,找了半天,发现是延迟更新标记加错了!!!以后一定要小心这一点
不用query,用value【1】也能ac,但是时间要的多,不知道是为什么,明明调用函数比较慢
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 const int maxn=100100; ll value[maxn<<2],add[maxn<<2]; void pushup(int rt)//向上更新 { value[rt]=value[rt<<1]+value[rt<<1|1]; } void pushdown(int rt,int m)//向下更新 { if(add[rt]) { add[rt<<1]=add[rt];//延迟标记向下更新 add[rt<<1|1]=add[rt]; value[rt<<1]=(m-(m>>1))*add[rt];//价值向下更新 value[rt<<1|1]=(m>>1)*add[rt]; add[rt]=0;//延迟标记清0 } } void btree(int l,int r,int rt) { add[rt]=0; if(l==r) { value[rt]=1; return ; } int m=(l+r)>>1; btree(ls); btree(rs); pushup(rt); } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R) { add[rt]=c; value[rt]=(ll)c*(r-l+1); return ; } pushdown(rt,r-l+1); int m=(l+r)>>1; if(L<=m)update(L,R,c,ls); if(R>m)update(L,R,c,rs); pushup(rt); } /*ll query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R)return value[rt]; pushdown(rt,r-l+1); int m=(l+r)>>1; ll ans=0; if(L<=m)ans+=query(L,R,ls); if(R>m)ans+=query(L,R,rs); return ans; }*/ int main() { int t,n,m; scanf("%d",&t); for(int i=1;i<=t;i++) { scanf("%d%d",&n,&m); btree(1,n,1); while(m--){ int a,b,c; scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,n,1); } printf("Case %d: The total value of the hook is %d.\n",i,value[1]); } return 0; }