题意分析:
一道有关线段树区间修改的入门题。线段树区间修改一般包含两个操作:设有一个数组Ai。1.把Ai,Ai+1,Ai+2....Ar的值全部添加v。2.把Ai,Ai+1,Ai+2....Ar的值全部修改成v.这道题考查的石第二个操作。如果你要是明白了线段树的点修改,这道题你看别人写的代码,你很容易就能明白。我就是一个活生生的例子。如果这道题你看明白了,我们可以想一下如果给你一道题,有关第一个操作的,我们该怎么做?我们可以在定义结构体的时候可以定义一个变量是求相对应的这段区间的和,还有一个变量是在这个区间经过几次的添添加加减减,最后这段区间最后要添加多少。PS:这几天HDU OJ登不上去了,我只是把代码敲下来了,不知道局部细节上面处理的怎么样,不知道能不能AC,但是大致思路肯定是对的。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
int lc,rc;
int val;
}s[1000000];
int a,b,c;
void build(int sta,int end,int index) {
if(sta == end) {
s[index].lc=sta;
s[index].rc=end;
s[index].val = 1;
return ;
}
int mid=(sta+end)/2;
s[index].val=1;
s[index].lc=sta;
s[index].rc=end;
build(sta,mid,2*index);
build(mid+1,end,2*index+1);
}
void updata(int lc,int rc,int index) {
if(s[index].val == c) {
return ;
}
if(s[index].lc==lc && s[index].rc==rc) {
s[index].val = c;
return ;
}
if(s[index].val) {
s[2*index].val=s[2*index+1].val=s[index].val;
}
s[index].val = 0;
int mid = (s[index].rc+s[index].lc)>>1;
if(rc<=mid) {
updata(lc,rc,2*index);
}
else if(lc>mid) updata(lc,rc,2*index+1);
else {
updata(lc,mid,2*index);
updata(mid+1,rc,2*index+1);
}
}
int sum(int index) {
if(s[index].val) return (s[index].rc-s[index].lc+1)*s[index].val;
return sum(2*index)+sum(2*index+1);
}
int main() {
int t,n,m,i;
scanf("%d",&t);
for(i=1; i<=t; i++) {
scanf("%d%d",&n,&m);
build(1,n,1);
for(int j=0; j<m; j++) {
cin>>a>>b>>c;
updata(a,b,1);
}
printf("Case %d: The total value of the hook is %d.\n",i,sum(1));
}
return 0;
}