一个语句顺序错了,我弄了2个小时才找到(细心才是王道)
这个题是线段树区间更新,区间查询
#include<stdio.h> #include<algorithm> #define maxn 100000*4+10 using namespace std; struct node { int l; int r; int value; int lazy; } tr[maxn]; int a[maxn]; void pushup(int ro) { tr[ro].value=tr[ro<<1].value+tr[ro<<1|1].value; } void pushdown(int ro) {if(tr[ro].lazy > 0){ tr[ro<<1].lazy=tr[ro].lazy; tr[ro<<1|1].lazy=tr[ro].lazy; tr[ro<<1].value=tr[ro].lazy*(tr[ro<<1].r-tr[ro<<1].l+1); tr[ro<<1|1].value=tr[ro].lazy*(tr[ro<<1|1].r-tr[ro<<1|1].l+1); tr[ro].lazy=0;} } void build(int ro,int l,int r) { tr[ro].l=l; tr[ro].r=r; tr[ro].lazy=0;//就是这,浪费了我2个小时 if(l==r) { tr[ro].value=a[l]; return; } int mid=(l+r)/2; build(ro*2,l,mid); build(ro*2+1,mid+1,r); pushup(ro); } void update(int ro,int ll,int rr,int val) { if(rr<tr[ro].l||ll>tr[ro].r) return ; if(tr[ro].l>=ll&&tr[ro].r<=rr) { tr[ro].lazy=val; tr[ro].value=val*(tr[ro].r-tr[ro].l+1); return; } pushdown(ro); int mid=(tr[ro].l+tr[ro].r)/2; // if(ll<=mid)//可要可不要 update(ro*2,ll,rr,val); // if(rr>mid)//可要可不要 update(ro*2+1,ll,rr,val); pushup(ro); } int query(int ro,int l,int r) { if(l<=tr[ro].l&&r>=tr[ro].r) return tr[ro].value; int mid=(tr[ro].l+tr[ro].r)/2; pushdown(ro); int res=0; if(r<=mid) res+=query(ro*2,l,r); else if(l>mid) res+=query(ro*2+1,l,r); else res+=query(ro*2,l,r)+query(ro*2+1,l,r); return res; } int main() { int i,t1,t2,t3=1,n; int x,y,z; scanf("%d",&t1); while(t1--) { scanf("%d",&n); for(i=1; i<=n; i++)a[i]=1; build(1,1,n); scanf("%d",&t2); while(t2--) { scanf("%d%d%d",&x,&y,&z); update(1,x,y,z); } printf("Case %d: The total value of the hook is %d. ",t3++,query(1,1,n)); } return 0; }我参考的代码段:
/* 线段树+修改区间+询问区间 */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> #include<iostream> #include<queue> #include<vector> #include<map> #include<math.h> typedef long long ll; //typedef __int64 int64; const int maxn = 100005; const int maxm = 1005; const int inf = 0x7FFFFFFF; const double pi = acos(-1.0); const double eps = 1e-8; using namespace std; #define LEFT( x ) (x<<1) #define RIGHT( x ) ((x<<1)+1) struct node{ int l,r,sum; int flag; }tree[ maxn<<2 ]; int data[ maxn ]; void pushup( int n ){ tree[ n ].sum = tree[ LEFT( n ) ].sum+tree[ RIGHT( n ) ].sum; return ; } void pushdown( int n,int m ){//下标为n,这段区间有m个数 if( tree[ n ].flag!=0 ){ tree[ LEFT( n ) ].flag = tree[ RIGHT( n ) ].flag = tree[ n ].flag; tree[ LEFT( n ) ].sum = tree[ n ].flag*(m-m/2);//tree[ n ].flag*((m+1)/2); tree[ RIGHT( n ) ].sum = tree[ n ].flag*(m/2);//tree[ n ].flag*( m-(m+1)/2 ); tree[ n ].flag = 0; } return; } void build( int l,int r,int n ){ if( l==r ){ tree[ n ].sum = data[ l ]; tree[ n ].flag = 0; tree[ n ].l=tree[ n ].r = l; return ; } tree[ n ].flag = 0; tree[ n ].l = l; tree[ n ].r = r; int mid; mid = (l+r)>>1; build( l,mid,LEFT( n ) ); build( mid+1,r,RIGHT( n ) ); pushup( n ); return; } void update( int a,int b,int c,int l,int r,int n ){ if( a==l&&b==r ){ tree[ n ].flag = c; tree[ n ].sum = (r-l+1)*c; return ; } pushdown( n,r-l+1 ); //printf("test "); int mid; mid = (l+r)>>1; if( mid>=b ) update( a,b,c,l,mid,LEFT( n ) ); else if( mid<a ) update( a,b,c,mid+1,r,RIGHT( n )); else { update( a,mid,c,l,mid,LEFT( n ) ); update( mid+1,b,c,mid+1,r,RIGHT( n ) ); } pushup( n ); return ; } int query( int a,int b,int l,int r,int n ){ if( a==l&&b==r ){ return tree[ n ].sum; } pushdown( n,r-l+1 ); int mid; mid = (l+r)>>1; if( mid>=b ) return query( a,b,l,mid,LEFT( n ) ); else if( mid<a ) return query( a,b,mid+1,r,RIGHT( n )); else return query( a,mid,l,mid,LEFT( n ) )+query( mid+1,b,mid+1,r,RIGHT( n )); } int main(){ int ca; scanf("%d",&ca); for( int t=1;t<=ca;t++ ){ int n; scanf("%d",&n); for( int i=1;i<=n;i++ ){ data[ i ] = 1; } build( 1,n,1 ); int op; scanf("%d",&op); while( op-- ){ 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. ",t,tree[ 1 ].sum); } return 0; }
贴上线段树延迟标记写法:
void pushup(int index){ tree[index].sum = tree[index<<1].sum+tree[index<<1|1].sum; tree[index].mx = max(tree[index<<1].mx,tree[index<<1|1].mx); tree[index].mn = min(tree[index<<1].mn,tree[index<<1|1].mn); } void pushdown(int index){ //说明该区间之前更新过 //要想更新该区间下面的子区间,就要把上次更新该区间的值向下更新 if(tree[index].add > 0){ //替换原来的值 /* tree[index<<1].sum = (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add; tree[index<<1|1].sum = (tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add; tree[index<<1].mx = tree[index].add; tree[index<<1|1].mx = tree[index].add; tree[index<<1].mn = tree[index].add; tree[index<<1|1].mn = tree[index].add; tree[index<<1].add = tree[index].add; tree[index<<1|1].add = tree[index].add; tree[index].add = 0;*/ //在原来的值的基础上加上val tree[index<<1].sum += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add; tree[index<<1|1].sum +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add; tree[index<<1].mx += tree[index].add; tree[index<<1|1].mx += tree[index].add; tree[index<<1].mn += tree[index].add; tree[index<<1|1].mn += tree[index].add; tree[index<<1].add += tree[index].add; tree[index<<1|1].add += tree[index].add; tree[index].add = 0; } }