正常的线段树
正常的线段树
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号
浙公网安备 33010602011771号