zoukankan      html  css  js  c++  java
  • bzoj1500:[NOI2005]维修数列

    Description

    Input

    输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目。第2行包含N个数字,描述初始时的数列。以下M行,每行一条命令,格式参见问题描述中的表格。

    Output

    对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

    Sample Input

    9 8
    2 -6 3 5 1 -5 -3 6 3
    GET-SUM 5 4
    MAX-SUM
    INSERT 8 3 -5 7 2
    DELETE 12 1
    MAKE-SAME 3 3 2
    REVERSE 3 6
    GET-SUM 5 4
    MAX-SUM

    Sample Output

    -1
    10
    1
    10

    HINT

    splay区间操作模板

    毒瘤一个,splay这个数据结构就够有毒了,一遍必卡,得苦逼的慢慢debug

    这题的数据范围也有毒性,必须回收被删掉的数

    否则MLE

    最大子序列啊什么的,线段树怎么维护的就怎么维护,反正这棵树维护的是树上的编号,而不是对应的值(这个不知道怎么表述,学久了就理解了)

    代码(巨难写,写过最长代码):

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<queue>
      5 using namespace std;
      6 int sz,root;
      7 int ch[800001][2],d[800001],v[800001],f[800001],size[800001],sum[800001],tot,mx[800001],lx[800001],rx[800001],id[800001],flag[800001];bool used[800001];
      8 int n,l,r,m;
      9 void read(int &x) {
     10     char ch; bool ok;
     11     for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
     12     for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
     13 }
     14 queue<int> s;
     15 inline bool get(int x)
     16 {
     17     return ch[f[x]][1]==x;
     18 }
     19 void update(int x)
     20 {
     21     int l=ch[x][0],r=ch[x][1];
     22     size[x]=size[l]+size[r]+1;
     23     sum[x]=sum[l]+sum[r]+v[x];
     24     mx[x]=max(mx[l],mx[r]);
     25     mx[x]=max(mx[x],lx[r]+v[x]+rx[l]);
     26     lx[x]=max(lx[l],sum[l]+v[x]+lx[r]);
     27     rx[x]=max(rx[r],sum[r]+v[x]+rx[l]);
     28 }
     29 void pushdown(int now)
     30 {
     31     int l=ch[now][0],r=ch[now][1];
     32     if(flag[now])
     33     {
     34         flag[now]=0;
     35         if(l)v[l]=v[now],flag[l]=1,sum[l]=size[l]*v[now];
     36         if(r)flag[r]=1,v[r]=v[now],sum[r]=size[r]*v[now];
     37         if(v[now]>=0)
     38         {
     39             if(l)lx[l]=rx[l]=mx[l]=sum[l];
     40             if(r)lx[r]=rx[r]=mx[r]=sum[r];
     41         }
     42         else
     43         {
     44             if(l)lx[l]=rx[l]=0,mx[l]=v[now];
     45             if(r)lx[r]=rx[r]=0,mx[r]=v[now];
     46         }
     47     }
     48     if(used[now])
     49     {
     50         swap(lx[l],rx[l]);swap(lx[r],rx[r]);
     51         swap(ch[l][0],ch[l][1]);swap(ch[r][0],ch[r][1]);
     52         used[now]^=1;
     53         used[l]^=1,used[r]^=1;
     54     }
     55 }
     56 void move(int now,int &k)
     57 {
     58     int fa=f[now],cnt=get(now),faa=f[fa];
     59     pushdown(fa);
     60     if(fa==k)k=now;
     61     else if(faa)ch[faa][get(fa)]=now;
     62     ch[fa][cnt]=ch[now][cnt^1];
     63     f[ch[now][cnt^1]]=fa;
     64     ch[now][cnt^1]=fa;
     65     f[fa]=now;
     66     f[now]=faa;
     67     update(fa);update(now);
     68 }
     69 void splay(int x,int &k)
     70 {
     71     int y,z;
     72     pushdown(x);
     73     while(x!=k)
     74     {
     75         y=f[x],z=f[y];
     76         if(y!=k)
     77         {
     78             if((ch[y][0]==ch[z][0])^(ch[y][1]==ch[z][1]))move(y,k);
     79             else move(x,k);
     80         }
     81         move(x,k);
     82     }
     83 }
     84 void build(int l,int r,int fa)
     85 {
     86     if(l>r)return;
     87     int mid=(l+r)>>1,now=id[mid],last=id[fa];
     88     if(l==r)
     89     {
     90         sum[now]=d[l];size[now]=1;
     91         if(d[l]>=0)lx[now]=rx[now]=mx[now]=d[l];
     92         else lx[now]=rx[now]=0,mx[now]=d[l];
     93     }
     94     else build(l,mid-1,mid),build(mid+1,r,mid);
     95     v[now]=d[mid];f[now]=last;update(now);
     96     ch[last][mid>=fa]=now;
     97 }
     98 int find(int k,int x)
     99 {
    100     pushdown(k);
    101     if(x<=size[ch[k][0]])return find(ch[k][0],x);
    102     if(x==size[ch[k][0]]+1)return k;
    103     return find(ch[k][1],x-size[ch[k][0]]-1);
    104 }
    105 void rec(int x)
    106 {
    107     if(!x)return;
    108     int l=ch[x][0],r=ch[x][1];
    109     rec(l);rec(r);s.push(x);
    110     f[x]=ch[x][0]=ch[x][1]=0;
    111     flag[x]=used[x]=0;
    112 }
    113 void ins(int k,int b)
    114 {
    115     for(int i=1;i<=b;i++)read(d[i]);
    116     for(int i=1;i<=b;i++)
    117         if(!s.empty())id[i]=s.front(),s.pop();
    118         else id[i]=++tot;
    119     build(1,b,0);
    120     int now=id[1+b>>1];
    121     int x=find(root,k+1),y=find(root,k+2);
    122     splay(x,root);splay(y,ch[root][1]);
    123     ch[y][0]=now;f[now]=y;
    124     update(y),update(x);
    125 }
    126 void del(int l,int r)
    127 {
    128     int x=find(root,l),y=find(root,r+1);
    129     splay(x,root),splay(y,ch[root][1]);
    130     rec(ch[y][0]);
    131     ch[y][0]=0;
    132     update(y),update(x);
    133 }
    134 void change(int k,int b,int num)
    135 {
    136     int x=find(root,k),y=find(root,b+1);
    137     splay(x,root),splay(y,ch[root][1]);
    138     int g=ch[y][0];
    139     flag[g]=1;sum[g]=num*size[g];v[g]=num;
    140     if(num>=0)lx[g]=rx[g]=mx[g]=sum[g];
    141     else lx[g]=rx[g]=0,mx[g]=num;
    142     update(y),update(x);
    143 }
    144 int main()
    145 {
    146     read(n),read(m);
    147     d[1]=d[n+2]=mx[0]=-9999999;
    148     for(int i=1;i<=n;i++)read(d[i+1]);
    149     for(int i=1;i<=n+2;i++)id[i]=i;
    150     build(1,n+2,0);
    151     int k,x,a,b,c;;tot=n+2;root=n+3>>1;
    152     char p[13];
    153     while(m--)
    154     {
    155         scanf("%s",p+1);
    156         if(p[3]=='V')//翻转 
    157         {
    158             read(a),read(b);b=b+a;
    159             int x=find(root,a),y=find(root,b+1);
    160             splay(x,root);
    161             splay(y,ch[root][1]);c=ch[y][0];
    162             used[c]^=1;swap(lx[c],rx[c]);swap(ch[c][0],ch[c][1]);
    163             update(y),update(x);    
    164         }
    165         if(p[3]=='S')//插入 
    166             read(a),read(b),ins(a,b);
    167         if(p[3]=='L')//删除 
    168         {
    169             read(a),read(b);b=a+b;
    170             del(a,b); 
    171         }
    172         if(p[3]=='K')//修改 
    173         {
    174             read(a),read(b);read(c);b=a+b;
    175             change(a,b,c);
    176         }
    177         if(p[3]=='T')//求和
    178         {
    179             read(a),read(b);b=a+b;
    180             splay(find(root,a),root);
    181             splay(find(root,b+1),ch[root][1]);
    182             printf("%d
    ",sum[ch[ch[root][1]][0]]);
    183         }
    184         if(p[3]=='X')//最大连续和
    185             printf("%d
    ",mx[root]);
    186     }
    187 }
  • 相关阅读:
    例题6-8 Tree Uva548
    例题6-7 Trees on the level ,Uva122
    caffe Mac 安装
    Codeforces Round #467 (Div. 1) B. Sleepy Game
    Educational Codeforces Round37 E
    Educational Codeforces Round 36 (Rated for Div. 2) E. Physical Education Lessons
    Good Bye 2017 E. New Year and Entity Enumeration
    Good Bye 2017 D. New Year and Arbitrary Arrangement
    Codeforces Round #454 D. Seating of Students
    浙大紫金港两日游
  • 原文地址:https://www.cnblogs.com/lcxer/p/9441560.html
Copyright © 2011-2022 走看看