题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698
题目大意:
线段树成段更新,区间求和,一开始setv忘记初始化了。。。WA了好几次
code:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAX=100005;
int _sum=0;
class IntervalTree
{
private:
int setv[MAX*4];
public:
int sumv[MAX*4];
void init()
{
memset(sumv,0,sizeof(sumv));
memset(setv,-1,sizeof(setv));//要记住初始化
}
void build(int o,int L,int R)
{
if(R==L)
{
sumv[o]=1;
setv[o]=1;
}
else
{
int M=(L+R)/2;
build(o*2,L,M);
build(o*2+1,M+1,R);
setv[o]=-1;
sumv[o]=sumv[o*2]+sumv[o*2+1];
}
}
void pushdown(int o)
{
if(setv[o]>=0)
{
setv[o*2]=setv[o*2+1]=setv[o];
setv[o]=-1;
}
}
void maintain(int o,int L,int R)
{
if(R>L)
{
sumv[o]=sumv[o*2]+sumv[o*2+1];
}
if(setv[o]>=0)
{
sumv[o]=setv[o]*(R-L+1);
}
}
void update(int o,int L,int R,int ql,int qr,int v)
{
if(ql<=L&&R<=qr)
{
setv[o]=v;
}
else
{
pushdown(o);
int M=(L+R)/2;
if(ql<=M)
update(o*2,L,M,ql,qr,v);
else
maintain(o*2,L,M);
if(qr>M)
update(o*2+1,M+1,R,ql,qr,v);
else
maintain(o*2+1,M+1,R);
}
maintain(o,L,R);
}
void query(int o,int L,int R,int ql,int qr)
{
if(setv[o]>=0)
{
_sum+=setv[o]*(min(R,qr)-max(L,ql)+1);
}
else
{
if(ql<=L&&R<=qr)
{
_sum+=sumv[o];
}
else
{
int M=(L+R)/2;
if(ql<=M)
query(o*2,L,M,ql,qr);
if(qr>M)
query(o*2+1,M+1,R,ql,qr);
}
}
}
};
IntervalTree tree;
int main()
{
int T;
while(cin>>T)
{
for(int kase=1;kase<=T;kase++)
{
int n,m;
scanf("%d",&n);
tree.init();
tree.build(1,1,n);
scanf("%d",&m);
_sum=0;
while(m--)
{
int a,b,v;
scanf("%d%d%d",&a,&b,&v);
tree.update(1,1,n,a,b,v);
}
tree.query(1,1,n,1,n);
printf("Case %d: The total value of the hook is %d.\n",kase,_sum);
}
}
return 0;
}