https://cn.vjudge.net/problem/POJ-3468 https://cn.vjudge.net/problem/HDU-1698
两者只有一个地方是不太一样的,就是他们需要处理的方式
POJ的是给你一个区间,让你加减一个数,从而改变区间的值,HDU是让你修改区间的值,而不是进行累加和累减的操作
先上POJ的
#include
#include
#include
using namespace std;
typedef long long ll;
const int MAX = 100005;
const int mod = 1e9 + 7;
ll c[MAX<<2];
ll lay[MAX<<2];
void push_down(int id,int l,int r,int mid)//这个函数里面同样是+ ;
{
if(lay[id])
{
c[id<<1]+=(ll)(mid-l+1)*lay[id];
c[id<<1|1]+=(ll)(r-mid)*lay[id];
lay[id<<1]+=lay[id];
lay[id<<1|1]+=lay[id];
lay[id]=0;
}
}
void push_up(int x)
{
c[x]=c[x<<1]+c[x<<1|1];
}
void build(int id,int l,int r)
{
if(l==r)
{ cin>>c[id];
// scanf("%d",&c[id]);
return;
}
int m=(l+r)>>1;
build(id<<1,l,m);
build(id<<1|1,m+1,r);
push_up(id);
}
void updata(int id,int l,int r,int L,int R,int V)
{
if(L<=l&&R>=r)
{
c[id]+=(ll)(r-l+1)*V;//这个地方是加上原来的区间数,因为你更改的数是要加上的
lay[id]+=(ll)V;return;//lay数组是说在id这个点需要加减的数,因此也是要+
}
int m=(l+r)>>1;
push_down(id,l,r,m);
if(L<=m)
updata(id<<1,l,m,L,R,V);
if(R>m) updata(id<<1|1,m+1,r,L,R,V);
push_up(id);
}
ll sum(int id,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
return c[id];
int m=(l+r)>>1;ll ans=0;
push_down(id,l,r,m);
if(L<=m)
ans+=sum(id<<1,l,m,L,R);
if(R>m) ans+=sum(id<<1|1,m+1,r,L,R);
return ans;
}
int main()
{
int n;int Q;
ios::sync_with_stdio(0);cin.tie(0);
//scanf("%d %d%*c",&n,&Q);
cin>>n>>Q;
int m=n;
build(1,1,n);
while(Q--)
{
char s;int x,y,v;
//scanf("%c%*c",&s);
cin>>s;
if(s=='Q'){
//scanf("%d %d",&x,&y);
cin>>x>>y;
//printf("%d\n",sum(1,1,n,x,y));
cout<>x>>y>>v;
updata(1,1,n,x,y,v);
}
}
return 0;
}
需要注意的是这道题需要Longlong的范围,否则WA
下面是HDU的
#include
using namespace std;
typedef long long ll;
const int MOD=1<<17;
ll n;
int lay[MOD<<1];//表示当前点的标记
int c[MOD<<1];//表示第i个点的值,因为线段树是从上往下建的,所以最低端的数才是最初的数据
void push_up(int x)
{
c[x]=c[x<<1]+c[x<<1|1];
}
void push_down(int id,int l,int r,int m)
{
if(lay[id])
{
c[id<<1]=(m-l+1)*lay[id];
c[id<<1|1]=(r-m)*lay[id];
lay[id<<1]=lay[id];
lay[id<<1|1]=lay[id];
lay[id]=0;
}
}
void build(int id,int l,int r)
{
if(l==r)
{
c[id]=1;
return ;
}
int m=(l+r)>>1;
build(id<<1,l,m);
build(id<<1|1,m+1,r);
push_up(id);
}
void update(int id,int l,int r,int now_l,int now_r,int val)
{
if(now_l<=l&&now_r>=r)
{
c[id]=(r-l+1)*val;//这里就是直接赋值,包括上面的push_down函数同样是赋值操作
if(l^r)//这一步就是判断是否找到最底部这样就不用再进行操作,去掉if语句也行
lay[id]=val;
return;
}
int m=(l+r)>>1;
push_down(id,l,r,m);
if(now_l<=m) update(id<<1,l,m,now_l,now_r,val);
if(now_r>m) update(id<<1|1,m+1,r,now_l,now_r,val);
push_up(id);
}
int sum(int id,int l,int r,int now_l,int now_r)
{
if(now_l<=l&&now_r>=r)
{
return c[id];
}
int m=(l+r)>>1;
int ans=0;
push_down(id,l,r,m);
if(now_l<=m) ans+=sum(id<<1,l,m,now_l,now_r);
if(now_r>=1+m) ans+=sum(id<<1|1,m+1,r,now_l,now_r);
return ans;
}
int main()
{
int t;
ios::sync_with_stdio(0);cin.tie(0);
cin>>t;
int q,x,y,z,n;
int s=1;
while(t--)
{
memset(lay,0,sizeof lay);
memset(c,0,sizeof c);
cin>>n>>q;
build(1,1,n);
//update(1,1,n,1,n,1);
while(q--)
{
cin>>x>>y>>z;
update(1,1,n,x,y,z);
}
cout<<"Case "<
其实HDU这道题只用update这个函数就可以,开始建树用update(1,1,n,1,n,1),输出c[1]就可以