首页 > 其他 > 详细

HDU - 4348 To the moon(主席树区间更新)

时间:2018-04-10 20:53:31      阅读:197      评论:0      收藏:0      [点我收藏+]

题目链接:To the moon

题意:给个数组,三种操作,第一种询问当前区间[l,r]的和,第二种给区间[l,r]的每一个数加上d,第三种询问在第几次修改后[l,r]的权值

题解:如果这题只询问区间和更新,简单建棵线段树维护区间和用延时标记就可以了,但是它询问第几次修改之后一段区间的值,这样的话刚才的方法就不好用,那我们可不可以,在每次修改之后的重新建一棵线段树呢?直接重新建的话空间会爆,这个时候就可以用??币的主席树(没学过主席树可以先做一下这个),每次的修改只会再新增logN个节点,先把给的数组,建好第一棵主席树(建的时候把add数组初始化为0),然后要然后之后的每次更新根据前面的主席树,只要新增(log(n)个节点)。然后询问的时候,用对应的主席树询问区间和就可以了。

  1 #include<bits/stdc++.h>
  2 #include<set>
  3 #include<cstdio>
  4 #include<iomanip>
  5 #include<iostream>
  6 #include<string>
  7 #include<cstring>
  8 #include<algorithm>
  9 #define pb push_back
 10 #define ll long long
 11 #define PI 3.14159265
 12 //#define ls l,m,rt<<1
 13 //#define rs m+1,r,rt<<1|1
 14 #define eps 1e-7
 15 typedef unsigned long long ull;
 16 const int mod=1e9+9;
 17 const ll inf=0x3f3f3f3f3f3f3f;
 18 const int maxn=1e5+5;
 19 const int N=1e4+7;
 20 using namespace std;
 21 int n,m,ls[maxn*30],rs[maxn*30],rt[maxn],t,tot;
 22 ll sum[maxn*30],add[maxn*30];
 23 char op[5];
 24 void built(int &o,int l,int r)
 25 {
 26     o=++tot;
 27     sum[o]=0;add[o]=0;
 28     if(l==r)
 29     {
 30         scanf("%lld",&sum[o]);return ;
 31     }
 32     int m=(l+r)>>1;
 33     built(ls[o],l,m);
 34     built(rs[o],m+1,r);
 35     sum[o]=sum[ls[o]]+sum[rs[o]];
 36 }
 37 void up(int rt,int l,int r)
 38 {
 39     int m=(l+r)>>1;
 40     sum[rt]=sum[ls[rt]]+sum[rs[rt]]+add[ls[rt]]*(m-l+1)+add[rs[rt]]*(r-m);
 41 }
 42 int update(int root,int l,int r,int L,int R,int val)
 43 {
 44     int newroot=++tot;
 45     add[newroot]=add[root];
 46     if(L<=l&&r<=R)
 47     {
 48         ls[newroot]=ls[root];
 49         rs[newroot]=rs[root];
 50         sum[newroot]=sum[root];
 51         add[newroot]=add[root]+val;
 52         return newroot;
 53     }
 54     int m=(l+r)>>1;
 55     if(L<=m)ls[newroot]=update(ls[root],l,m,L,R,val);
 56     else ls[newroot]=ls[root];
 57     if(R>m)rs[newroot]=update(rs[root],m+1,r,L,R,val);
 58     else rs[newroot]=rs[root];
 59     up(newroot,l,r);
 60     return newroot;
 61 }
 62 ll query(int rt,int l,int r,int L,int R,ll val)
 63 {
 64     if(L<=l&&r<=R)
 65     {
 66         return sum[rt]+1ll*(add[rt]+val)*(r-l+1);
 67     }
 68     int m=(l+r)>>1;
 69     ll ans=0;
 70     if(L<=m)ans+=query(ls[rt],l,m,L,R,val+add[rt]);
 71     if(R>m)ans+=query(rs[rt],m+1,r,L,R,val+add[rt]);
 72     return ans;
 73 }
 74 int main()
 75 {
 76     int l,r,val,T;
 77     while(~scanf("%d %d",&n,&m))
 78     {
 79         tot=0;t=0;
 80         built(rt[0],1,n);
 81         while(m--)
 82         {
 83             scanf("%s",op);
 84             if(op[0]==Q)
 85             {
 86                 scanf("%d %d",&l,&r);
 87                 printf("%lld\n",query(rt[t],1,n,l,r,0));
 88             }
 89             else if(op[0]==C)
 90             {
 91 
 92                 scanf("%d %d %d",&l,&r,&val);
 93                 rt[t+1]=update(rt[t],1,n,l,r,val);
 94                 t++;
 95             }
 96             else if(op[0]==H)
 97             {
 98                 scanf("%d %d %d",&l,&r,&T);
 99                 printf("%lld\n",query(rt[T],1,n,l,r,0));
100             }
101             else
102             {
103                 scanf("%d",&T);
104                 tot=rt[T+1];
105                 t=T;
106             }
107         }
108     }
109     return 0;
110 }

 

 

HDU - 4348 To the moon(主席树区间更新)

原文:https://www.cnblogs.com/lhclqslove/p/8782635.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!