您的位置:首页 > 其它

A Simple Problem with Integers POJ - 3468

2017-08-09 16:28 225 查看
点击打开链接

最近刚接触线段树 感觉很神奇

这道题是区间修改区间查询 pre[n*4]数组是关键(此题可以和懒惰标记合并)

只要pre[cur]不为零 就说明有上一次未完成的更新 这里的pre[cur]应该是“+=”而不是“=”

因为可能存在这种情况 上一次你在该点打了懒惰标记 但是还未及更新其子节点 这一次的更新又来到此点 此时用“=”会将上一次的覆盖 WA了好几次。。

#include <stdio.h>

long long sum[400001],pre[400001];
int laz[400001];
int n;

void pushup(int cur);
void pushdown(int len,int cur);
void build(int l,int r,int cur);
void update(int ll,int rr,long long val,int l,int r,int cur);
long long query(int ll,int rr,int l,int r,int cur);

int main()
{
long long c;
int q,i,a,b;
char ch[2];
while(scanf("%d%d",&n,&q)!=EOF)
{
for(i=1;i<=n*4;i++)
{
sum[i]=0;
pre[i]=0;
laz[i]=0;
}
build(1,n,1);
while(q--)
{
scanf("%s",ch);
if(ch[0]=='C')
{
scanf("%d%d%lld",&a,&b,&c);
update(a,b,c,1,n,1);
}
else
{
scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,1,n,1));
}
}
}
return 0;
}

void pushup(int cur)
{
sum[cur]=sum[cur*2]+sum[cur*2+1];
return;
}

void pushdown(int len,int cur)
{
if(laz[cur]==1)
{
sum[cur*2]+=pre[cur]*(len-len/2);
pre[cur*2]+=pre[cur];
laz[cur*2]=1;
sum[cur*2+1]+=pre[cur]*(len/2);
pre[cur*2+1]+=pre[cur];
laz[cur*2+1]=1;
pre[cur]=0;
laz[cur]=0;
}
return;
}

void build(int l,int r,int cur)
{
int m;
if(l==r)
{
scanf("%lld",&sum[cur]);
return;
}
m=(l+r)/2;
build(l,m,cur*2);
build(m+1,r,cur*2+1);
pushup(cur);
return;
}

void update(int ll,int rr,long long val,int l,int r,int cur)
{
int m;
if(ll<=l&&r<=rr)
{
sum[cur]+=(r-l+1)*val;
pre[cur]+=val;
laz[cur]=1;
return;
}
pushdown(r-l+1,cur);
m=(l+r)/2;
if(ll<=m) update(ll,rr,val,l,m,cur*2);
if(rr>m) update(ll,rr,val,m+1,r,cur*2+1);
pushup(cur);
return;
}

long long query(int ll,int rr,int l,int r,int cur)
{
long long ans;
int m;
if(ll<=l&&r<=rr)
{
return sum[cur];
}
pushdown(r-l+1,cur);
ans=0,m=(l+r)/2;
if(ll<=m) ans+=query(ll,rr,l,m,cur*2);
if(rr>m) ans+=query(ll,rr,m+1,r,cur*2+1);
return ans;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: