zoukankan      html  css  js  c++  java
  • SPOJ TTM

        这道题一眼看去就是一个可持久化线段树,但是是区间修改,由于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 }
  • 相关阅读:
    分零食「JSOI 2012」
    礼物「AHOI / HNOI2017」
    力「ZJOI2014」
    修改权值「多校联考2019」
    哪吒闹海「多校联考2019」
    消失之物
    灵异事件
    BZOJ1297: [SCOI2009]迷路
    BZOJ3445: [Usaco2014 Feb] Roadblock
    Luogu3953:逛公园
  • 原文地址:https://www.cnblogs.com/lvyouyw/p/6863246.html
Copyright © 2011-2022 走看看