1 10 2 1 5 2 5 9 3
Case 1: The total value of the hook is 24.
线段树 区间更新 区间求和
#include<stdio.h> #define MAXN 200001 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int num[MAXN<<2]; int top[MAXN<<2]; void PushUP(int rt) { num[rt]=num[rt<<1]+num[rt<<1|1]; } void PushDown(int rt,int m) { if(top[rt]) { top[rt<<1]=top[rt<<1|1]=top[rt]; num[rt<<1]=top[rt]*(m-(m>>1)); num[rt<<1|1]=top[rt]*(m>>1); top[rt]=0; } } void build(int l,int r,int rt) { top[rt]=0; if(l==r) { num[rt]=1; return ; } int m=(l+r)>>1; build(lson); build(rson); PushUP(rt); } void update(int L,int R,int tmp,int l,int r,int rt) { if(L<=l && r<=R) { top[rt]=tmp; num[rt]=tmp*(r-l+1); return ; } PushDown(rt,r-l+1); int m=(l+r)>>1; if(m>=L) update(L,R,tmp,lson); if(m<R) update(L,R,tmp,rson); PushUP(rt); } int main(void) { int T,t; // freopen("d:\\in.txt","r",stdin); scanf("%d",&T); for(t=1;t<=T;t++) { int n,q,X,Y,Z; scanf("%d%d",&n,&q); build(1,n,1); while(q--) { scanf("%d%d%d",&X,&Y,&Z); update(X,Y,Z,1,n,1); } printf("Case %d: The total value of the hook is %d.\n",t,num[1]); } return 0; }
按照自己对线段树的理解重新写的代码,没必要一直求和,最后求就好了,开一个数组就好了,num[rt]表示区间内的值是多少,为0的时候代表区间里的值不统一.。
#include<cstdio> #define maxn 110000 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int num[maxn<<2]; void PushDown(int rt) { num[rt<<1]=num[rt<<1|1]=num[rt]; num[rt]=0; } void build(int l,int r,int rt) { num[rt]=0; if(l==r) { num[rt]=1; return ; } int m=(l+r)>>1; build(lson); build(rson); } void updata(int l,int r,int rt,int L,int R,int x) { if(l>=L && r<=R) { num[rt]=x; return ; } if(num[rt]) PushDown(rt); int m=(l+r)>>1; if(L<=m) updata(lson,L,R,x); if(R>m) updata(rson,L,R,x); } int Sum(int l,int r,int rt) { if(num[rt]) return (r-l+1)*num[rt]; int m=(l+r)>>1; return Sum(lson)+Sum(rson); } int main() { int T,N,Q; int x,y,z,t=1; scanf("%d",&T); while(T--) { scanf("%d%d",&N,&Q); build(1,N,1); while(Q--) { scanf("%d%d%d",&x,&y,&z); updata(1,N,1,x,y,z); } printf("Case %d: The total value of the hook is %d.\n",t++,Sum(1,N,1)); } return 0; }