线段数组
改了好久才改出来,就是在更新时,的范围出错了:注意:::::特别注意;在求算范围是分别在左右孩子时,即不应该是直接减再乘以改后的数。而是在求出中间值,在分别到两边个求出其值来!具体解释见代码:如下代码:
http://acm.hdu.edu.cn/showproblem.php?pid=1698
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
# define MAX 100005
using namespace std;
int val[MAX<<2],sum_max[MAX<<2];
void push_down(int l,int r,int rt)
{
if(val[rt])
{
int mind=(l+r)>>1;
val[2*rt]= val[2*rt+1]=val[rt];
sum_max[rt*2]=(mind-l+1)*val[rt];
sum_max[rt*2+1]=(r-mind)*val[rt];
val[rt]=0;
}
}
void make_tree(int l,int r,int rt)
{
val[rt]=0;
if(l==r)
{
sum_max[rt]=1;
return ;
}
int mind=(l+r)>>1;
make_tree(l,mind,rt*2);
make_tree(mind+1,r,rt*2+1);
sum_max[rt]=sum_max[rt*2]+sum_max[rt*2+1];
}
void update(int l,int r,int rt,int a,int b,int c)
{
if(l>=a&&b>=r)
{
sum_max[rt]=(r-l+1)*c;
val[rt]=c;
return ;
}
push_down(l,r,rt);
int mind=(l+r)>>1;
if(a>mind) update(mind+1,r,rt*2+1,a,b,c);
else if(b<=mind) update(l,mind,rt*2,a,b,c);
else
{
update(l,mind,rt*2,a,mind,c);//注意后面的所求的范围也要变就不是(update(l,mind,rt*2,a,b,c),update (mind+1,r,rt*2+1,a,b,c);)
update(mind+1,r,rt*2+1,mind+1,b,c);//这里的范围,并不是与求其他的,这里是成段更新的数据,贴别注意!
}
sum_max[rt]=sum_max[rt*2]+sum_max[rt*2+1];
}
int main()
{
int t,n,m,k=0;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
make_tree(1,n,1);
int a,b,v;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&v);
update(1,n,1,a,b,v);
}
printf("Case %d: The total value of the hook is %d.\n",++k,sum_max[1]);
}
return 0;
}