您的位置:首页 > 其它

...

2016-03-17 22:44 197 查看
POJ 3468

线段树的成段更新加延迟标记

#include<string.h>
#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
typedef long long LL;
const int MAXN=111150;
struct Node
{
int l,r;
LL v;
LL c;
}ST[MAXN*3];
void lazysn(int i)//减少了搜索子结点的次数
{
if(ST[i].c)
{
ST[i<<1].c+=ST[i].c;
ST[i<<1|1].c+=ST[i].c;
ST[i<<1].v+=(LL)(ST[i<<1].r-ST[i<<1].l+1)*ST[i].c;
ST[i<<1|1].v+=(LL)(ST[i<<1|1].r-ST[i<<1|1].l+1)*ST[i].c;
ST[i].c=0;
}
}
void Build(int l,int r,int i)
{
ST[i].c=0;
ST[i].l=l;
ST[i].r=r;
int mid=(l+r)>>1;
if(l==r)
{
scanf("%I64d",&ST[i].v);
return ;
}
Build(l,mid,i<<1);
Build(mid+1,r,i<<1|1);
ST[i].v=ST[i<<1].v+ST[i<<1|1].v;
}
void update(int l,int r,int c,int i)
{
int mid=(ST[i].l+ST[i].r)>>1;
if(ST[i].l>=l&&ST[i].r<=r)
{
ST[i].c+=c;
ST[i].v+=(LL)c*(ST[i].r-ST[i].l+1);
return ;
}//如果没找到符合条件的点,那么就要递归进入子结点
lazysn(i);//所以要结束lazy标记,将子结点的值更新
if(r>mid)
update(l,r,c,i<<1|1);
if(l<=mid)
update(l,r,c,i<<1);
ST[i].v=ST[i<<1].v+ST[i<<1|1].v;
}
/*void prin(int l,int r,int i)
{
printf("[%d,%d]:c:%I64d  v:%I64d\n",ST[i].l,ST[i].r,ST[i].c,ST[i].v);
if(l==r)
{
return ;
}
int mid=(l+r)>>1;
prin(l,mid,i<<1);
prin(mid+1,r,i<<1|1);
}*/
LL query(int l,int r,int i)
{
LL ans=0;
int mid=(ST[i].l+ST[i].r)>>1;
if(ST[i].l>=l&&ST[i].r<=r)
{
return ST[i].v;
}
lazysn(i);//同上
if(r>mid)
ans+=query(l,r,i<<1|1);
if(l<=mid)
ans+=query(l,r,i<<1);
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n,m,l,r,c;
scanf("%d%d",&n,&m);
Build(1,n,1);
char s[5];
while(m--)
{
scanf("%s",s);
if(s[0]=='C')
{
scanf("%d%d%d",&l,&r,&c);
update(l,r,c,1);
//prin(1,n,1);
}
else
{
scanf("%d%d",&l,&r);
printf("%I64d\n",query(l,r,1));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: