//4671914 2011-09-28 15:07:14 Accepted 1698 843MS 3260K 1905 B G++ nkhelloworld //4671915 2011-09-28 15:07:18 Accepted 1698 453MS 3304K 1905 B C++ nkhelloworld //线段树解决,近似序列求和问题,简单 /* 一个N<=100000个数组成的序列,最多做Q<=100000次操作,每一次操作由a,b,c组成, 意思是将[a,b]区间的值修改为c,求经过Q次操作后序列的总和 */ #include <cstdio> #define MAXN 100000 struct SEGMENTTREE { int left,right,color; }tree[MAXN*4+1]; void buildsegtree(int root,int l,int r) { tree[root].left = l; tree[root].right = r; tree[root].color = 1; if(l != r) { int mid = (l+r)>>1; buildsegtree(root<<1,l,mid); buildsegtree(root<<1|1,mid+1,r); } } void update(int root,int a,int b,int c) { if(tree[root].left == tree[root].right) { tree[root].color = c; return ; } if(tree[root].color != 0) { tree[root<<1].color = tree[root].color; tree[root<<1|1].color = tree[root].color; tree[root].color = 0; } if(a == tree[root].left && b == tree[root].right) { tree[root].color = c; return ; } int mid = (tree[root].left + tree[root].right) >>1; if( b <= mid ) update(root<<1,a,b,c); else if(a > mid) update(root<<1|1,a,b,c); else { update(root<<1,a,mid,c); update(root<<1|1,mid+1,b,c); } } int query(int root,int left,int right) { if(tree[root].color!=0) return (right - left + 1) * tree[root].color; int mid = (left + right) >> 1; if(right <= mid) return query(root<<1, left, right); else if(left > mid) return query(root<<1|1, left,right); else return query(root<<1, left, mid) + query(root<<1|1, mid+1,right); } int main() { int totcase,numcase,i,n,q,a,b,c; scanf("%d",&totcase); for(numcase = 1;numcase <= totcase; numcase++) { scanf("%d%d",&n,&q); buildsegtree(1,1,n); for(i=1;i<=q;i++) { scanf("%d%d%d",&a,&b,&c); update(1,a,b,c); } printf("Case %d: The total value of the hook is %d.\n",numcase,query(1,1,n)); } return 0; }