正常的线段树
正常的线段树
zkw线段树的区间修改实在是不明白……
差分和前缀和的前缀和是什么gui……
还是用正常的写了一发(数据大一定要用输入输出优化,大概能节省1/4的时间)
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define rep(i,x,y) for (int i=x;i<=y;i++)
#define dep(i,y,x) for (int i=y;i>=x;i--)
using namespace std;
const int maxn=200000+10;
int n,m,type,l,r,k,a[maxn],T[maxn*3],tag[maxn*3];
int build_tree(int k,int l,int r)
{
int mid=(l+r)>>1;
T[k]=((l==r)?a[l]:(build_tree((k<<1),l,mid)+build_tree((k<<1)+1,mid+1,r)));
return T[k];
}
void update(int k,int l,int r,int val)
{
T[k]+=(r-l+1)*val;
if (l<r) tag[k]+=val;
}
void pushdown(int k,int l,int r)
{
int mid=(l+r)>>1;
if (l<r) update((k<<1),l,mid,tag[k]),update((k<<1)+1,mid+1,r,tag[k]);
tag[k]=0;
}
void add(int k,int l,int r,int x,int y,int val)
{
if ((x<=l)&&(r<=y))
update(k,l,r,val);
else
{
int mid=(l+r)>>1;
if (tag[k]) pushdown(k,l,r);
if (x<=mid) add((k<<1),l,mid,x,y,val);
if (y>mid) add((k<<1)+1,mid+1,r,x,y,val);
T[k]=T[(k<<1)]+T[(k<<1)+1];
}
}
int query(int k,int l,int r,int x,int y)
{
if ((x<=l)&&(r<=y))
return T[k];
else
{
int mid=(l+r)>>1,ans=0;
if (tag[k]) pushdown(k,l,r);
if (x<=mid) ans+=query((k<<1),l,mid,x,y);
if (y>mid) ans+=query((k<<1)+1,mid+1,r,x,y);
T[k]=T[(k<<1)]+T[(k<<1)+1];
return ans;
}
}
int main()
{
scanf("%d",&n);
rep(i,1,n) scanf("%d",&a[i]);
T[1]=build_tree(1,1,n);
scanf("%d",&m);
rep(i,1,m)
{
scanf("%d",&type);
if (type==1)
{
scanf("%d%d%d",&l,&r,&k);
add(1,1,n,l,r,k);
}
else
{
scanf("%d%d",&l,&r);
printf("%d\n",query(1,1,n,l,r));
}
}
return 0;
}

浙公网安备 33010602011771号