一点点想当然的想法使得我WA了6次...
对线段树的理解又深了一点。
熟悉了加标记的操作。
#include<iostream> #include<cstdio> #define MAXN 111111 using namespace std; int tree[MAXN<<2]; int flag[MAXN<<2]; void PushUp( int rt ){ tree[rt]=tree[rt<<1]+tree[rt<<1|1]; } void PushDown( int l,int r,int rt ) { if( flag[rt] ) { int m=(r+l)>>1; flag[rt<<1]=flag[rt<<1|1]=flag[rt]; //tree[rt<<1]=tree[rt]*(m-l+1)/(r-l+1); tree[rt<<1]=flag[rt]*(m-l+1); //tree[rt<<1]=flag[rt]*(m-(m>>1)); //tree[rt<<1|1]=tree[rt]*(r-m)/(r-l+1); tree[rt<<1|1]=flag[rt]*(r-m); //tree[rt<<1|1]=flag[rt]*(m>>1); flag[rt]=0; } } void build( int l,int r,int rt ) { flag[rt]=0; tree[rt]=1; if( l==r ) return ; int m=(l+r)>>1; build( l,m,rt<<1 ); build( m+1,r,rt<<1|1 ); PushUp(rt); } void update( int L,int R,int v,int l,int r,int rt ) { if( L<=l&&r<=R ) { tree[rt]=(r-l+1)*v; flag[rt]=v; return ; } PushDown(l,r,rt); int m=(l+r)>>1; if( L<=m ) update( L,R,v,l,m,rt<<1 ); if( m+1<=R ) update( L,R,v,m+1,r,rt<<1|1 ); /**else { update( L,R,v,l,m,rt<<1 ); update( L,R,v,m+1,r,rt<<1|1 ); }*/ PushUp(rt); } int main() { int T,cases=1; scanf( "%d",&T ); while( T-- ) { memset( flag,0,sizeof(flag) ); int N; scanf( "%d",&N ); build( 1,N,1 ); int Q; scanf( "%d",&Q ); int x,y,z; while( Q-- ) { scanf( "%d %d %d",&x,&y,&z ); update( x,y,z,1,N,1 ); //printf( "%d\n",tree[1] ); } printf( "Case %d: The total value of the hook is %d.\n",cases++,tree[1] ); } return 0; }