算法整理

线段树模板

#include
#define N 200100
int n,Q,tot=0,x;
long long a[200100];
struct tree
{
    int left,right;
    int rptr,lptr;
    long long sum;
    long long bj;
}t[N*4];
void buildtree(int ll,int rr)
{
    int cur=++tot; 
    t[cur].left=ll;
    t[cur].right=rr;
    if (ll+1!=rr)
      {
           t[cur].lptr=tot+1;
           buildtree(ll,(ll+rr)/2);
           t[cur].rptr=tot+1;
           buildtree((ll+rr)/2,rr);
           t[cur].sum=t[t[cur].lptr].sum+t[t[cur].rptr].sum;
      }
    else t[cur].sum=a[ll];
}
void update(long long k)
{
    t[t[k].lptr].sum+=(t[t[k].lptr].right-t[t[k].lptr].left)*t[k].bj;
    t[t[k].rptr].sum+=(t[t[k].rptr].right-t[t[k].rptr].left)*t[k].bj;
    t[t[k].lptr].bj+=t[k].bj;
    t[t[k].rptr].bj+=t[k].bj;
    t[k].bj=0;
}
void change(int k,int ll,int rr,long long delta)
{
    if (ll<=t[k].left&&rr>=t[k].right)
      {
          t[k].sum+=(t[k].right-t[k].left)*delta;
          t[k].bj+=delta;
      }
    else 
      {
          if (t[k].bj) update(k);
          if (ll<(t[k].left+t[k].right)/2)
            change(t[k].lptr,ll,rr,delta);
          if (rr>(t[k].left+t[k].right)/2)
            change(t[k].rptr,ll,rr,delta);
          t[k].sum=t[t[k].lptr].sum+t[t[k].rptr].sum;
      }    
}
long long find(int  k,int ll,int rr)
{
    if (ll<=t[k].left&&rr>=t[k].right)
       return t[k].sum;
    long long ans=0;
    if (t[k].bj) update(k);
    if (ll<(t[k].left+t[k].right)/2)
      ans+=find(t[k].lptr,ll,rr);
    if (rr>(t[k].left+t[k].right)/2)
      ans+=find(t[k].rptr,ll,rr);
    return ans;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
      scanf("%lld",&a[i]);
    buildtree(1,n+1);//注意由于区间是左闭右开,所以右边的数加一,下同 
    scanf("%d",&Q);
    for (int i=1;i<=Q;i++)
      {         
           int f;
           scanf("%d",&f);
           if (f==1)
             {
                   int a,b;
                   scanf("%d%d%lld",&a,&b,&x);
                change(1,a,b+1,x);
           }
        else 
          {
               int a,b;
               scanf("%d%d",&a,&b);
               printf("%lld\n",find(1,a,b+1));//别忘了换行 
          }
      }
    return 0;
}

 

转载于:https://www.cnblogs.com/suijunyao/p/5565110.html

你可能感兴趣的:(算法整理)