这道题一眼看去就是一个可持久化线段树,但是是区间修改,由于wyx说此题复杂度是O(nlogn)的,我就没写树套树,然后就自己yy了一个离线做法。

    我们考虑直接模拟这个过程,对于一个B操作,我们直接将之前的操作的影响清除,这样每个操作最多会被计算2次,但是有一个问题就是H操作不太好弄,我们可以先离线下来,然后维护一下H操作的这个时间t被经过了多少次,这样我们就知道这个H操作是我们第几次模拟后的查询,这样就可以通过一个普通的线段树来维护了。

    这道题好像正解是区间修改的主席树,我之前只会写套上树状数组的,不过感觉这个没什么用...就先不学了吧..

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<vector>
  5 using namespace std;
  6 #define maxn 100005
  7 typedef long long LL;
  8 struct tree
  9 {
 10     int l,r;
 11     LL sum,lazy;
 12 }t[maxn*4];
 13 struct ask
 14 {
 15     int opt,l,r,d,t;
 16 }q[maxn];
 17 int n,m,T,cnt[maxn],st[maxn],top,cur[maxn],a[maxn];
 18 LL ans[maxn];
 19 vector<pair<int,int> > g[maxn];
 20 
 21 inline int read(void) 
 22 {
 23     int x=0,f=1;
 24     char ch=getchar();
 25     while (ch>'9'||ch<'0') 
 26     {
 27         if (ch=='-') f=-1;
 28         ch=getchar();
 29     }
 30     while (ch>='0'&&ch<='9') 
 31     {
 32         x=x*10+ch-'0';
 33         ch=getchar();
 34     }
 35     return x*f;
 36 }
 37 
 38 void build(int x,int l,int r) 
 39 {
 40     t[x].l=l;t[x].r=r;
 41     if (l==r) 
 42     {
 43         t[x].sum=a[l];
 44         return;
 45     }
 46     int mid=(l+r)>>1;
 47     build(2*x,l,mid);
 48     build(2*x+1,mid+1,r);
 49     t[x].sum=t[2*x].sum+t[2*x+1].sum;
 50 }
 51 
 52 void update(int x)
 53 {
 54     t[2*x].sum+=t[x].lazy*(t[2*x].r-t[2*x].l+1);
 55     t[2*x+1].sum+=t[x].lazy*(t[2*x+1].r-t[2*x+1].l+1);
 56     t[2*x].lazy+=t[x].lazy;
 57     t[2*x+1].lazy+=t[x].lazy;
 58     t[x].lazy=0;
 59 }
 60 
 61 void change(int x,int l,int r,int z) 
 62 {
 63     if (t[x].l==l&&t[x].r==r) 
 64     {
 65         t[x].sum+=(LL)z*(r-l+1);
 66         t[x].lazy+=z;
 67         return;
 68     }
 69     if (t[x].lazy) update(x);
 70     int mid=(t[x].l+t[x].r)>>1;
 71     if (l>mid) change(2*x+1,l,r,z);
 72     else if (r<=mid) change(2*x,l,r,z);
 73     else 
 74     {
 75         change(2*x,l,mid,z);
 76         change(2*x+1,mid+1,r,z);
 77     }
 78     t[x].sum=t[2*x].sum+t[2*x+1].sum;
 79 }
 80 
 81 LL query(int x,int l,int r) 
 82 {
 83     if (t[x].l==l&&t[x].r==r) return t[x].sum;
 84     if (t[x].lazy) update(x);
 85     int mid=(t[x].l+t[x].r)>>1;
 86     if (l>mid) return query(2*x+1,l,r);
 87     else if (r<=mid) return query(2*x,l,r);
 88     else return query(2*x,l,mid)+query(2*x+1,mid+1,r);
 89 }
 90 
 91 int main()
 92 {
 93     n=read();m=read();
 94     for (int i=1;i<=n;i++) a[i]=read();
 95     for (int i=1;i<=m;i++)
 96     {
 97         char s[3];
 98         scanf("%s",s);
 99         if (s[0]=='C') 
100         {
101             q[i].opt=1;cnt[++T]++;
102             q[i].l=read();q[i].r=read();q[i].d=read();
103             q[i].t=T;
104         }
105         if (s[0]=='Q') 
106         {
107             q[i].opt=2;q[i].l=read();
108             q[i].r=read();g[T].push_back(make_pair(cnt[T],i));
109             q[i].t=T;
110         }
111         if (s[0]=='H') 
112         {
113             q[i].opt=3;q[i].l=read();q[i].r=read();
114             int t=read();
115             g[t].push_back(make_pair(cnt[t],i));
116             q[i].t=t;
117         }
118         if (s[0]=='B') 
119         {
120             q[i].opt=4;q[i].d=read();q[i].t=T;
121             T=q[i].d;
122         }
123     }
124     build(1,1,n);T=0;
125     for (int i=1;i<=m;i++) 
126         if ((q[i].opt==3||q[i].opt==2)&&q[i].t==0) 
127             ans[i]=query(1,q[i].l,q[i].r);
128     memset(cnt,0,sizeof cnt);
129     for (int i=1;i<=m;i++) 
130     {
131         if (q[i].opt==2||q[i].opt==3) continue;
132         if (q[i].opt==1) 
133         {
134             cnt[++T]++;
135             change(1,q[i].l,q[i].r,q[i].d);
136             st[++top]=i;
137             int siz=g[T].size();
138             while (cur[T]<siz&&cnt[T]==g[T][cur[T]].first)
139             {
140                 int id=g[T][cur[T]].second;
141                 ans[id]=query(1,q[id].l,q[id].r);
142                 cur[T]++;
143             }
144         }
145         if (q[i].opt==4) 
146         {
147             while (top>0&&q[st[top]].t>q[i].d)  
148                 change(1,q[st[top]].l,q[st[top]].r,-q[st[top]].d),top--;
149             T=q[i].d;
150         }
151     }
152     for (int i=1;i<=m;i++) 
153         if (q[i].opt==2||q[i].opt==3) printf("%lld\n",ans[i]);
154     return 0;
155 }

 

posted on 2017-05-16 19:33  Vergil_LY  阅读(231)  评论(0编辑  收藏  举报