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

    Input

    输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。 第2行包含N个数字,描述初始时的数列。 以下M行,每行一条命令,格式参见问题描述中的表格。 任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。 插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

    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
    题解:
    splay,几乎所有模式都在里面
    注意这个splay维护的是位置
    插入:将第pos旋到根,第pos+1(名次树操作)旋到根的右子树
    这里的插入用了一种二分的方法,可以保证有序,且可以直接反转
    删除:将第pos旋到根,第pos+tot+1旋到根的右子树
    如果用了内存池还要递归回收(详见erase)
    反转:留下反转标记,每次直接交换左右节点
    修改同上,注意0
    求和直接维护
    求最大子序列和有点复杂,维护节点最大子序列和,右端最大和,左端最大和,详见(pushdown)
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 const int MAXN=500010;
      7 int tot2,tot1,s[MAXN],pre[MAXN],ch[MAXN][2],key[MAXN],sum[MAXN],maxsum[MAXN],lx[MAXN],rx[MAXN],a[MAXN];
      8 int size[MAXN],same[MAXN],root,n,m;
      9 bool rev[MAXN];
     10 int gi()
     11 {
     12     char ch=getchar();int s=0;int sign=1;
     13     while (ch<'0'||ch>'9')
     14     {if (ch=='-') sign=-1;ch=getchar();}
     15     while (ch>='0'&&ch<='9')
     16     {s=s*10+ch-'0';ch=getchar();}
     17 return s*sign;
     18 }
     19 void NewNode(int &r,int fa,int k)
     20 {
     21     if (tot2) r=s[tot2--];
     22     else
     23         r=++tot1;
     24     pre[r]=fa;
     25     ch[r][0]=ch[r][1]=0;
     26     key[r]=k;
     27     sum[r]=k;
     28     rev[r]=same[r]=0;
     29     lx[r]=rx[r]=maxsum[r]=k;
     30     size[r]=1;
     31 }
     32 void pushup(int x)
     33 {
     34     int lson=ch[x][0],rson=ch[x][1];
     35     size[x]=size[lson]+size[rson]+1;
     36     sum[x]=sum[lson]+sum[rson]+key[x];
     37     lx[x]=max(lx[lson],sum[lson]+key[x]+max(0,lx[rson]));
     38     rx[x]=max(rx[rson],sum[rson]+key[x]+max(0,rx[lson]));
     39     maxsum[x]=max(0,rx[lson])+key[x]+max(0,lx[rson]);
     40     maxsum[x]=max(maxsum[lson],max(maxsum[x],maxsum[rson]));
     41 }
     42 void update_same(int x,int c);
     43 void update_Reverse(int x);
     44 void pushdown(int x)
     45 {
     46     if (same[x])
     47     {
     48         update_same(ch[x][0],key[x]);
     49         update_same(ch[x][1],key[x]);
     50         same[x]=0;
     51     }
     52     if (rev[x])
     53     {
     54         update_Reverse(ch[x][0]);
     55         update_Reverse(ch[x][1]);
     56         rev[x]=0;
     57     }
     58 }
     59 void build(int &x,int l,int r,int fa)
     60 {
     61     if (l>r) return;
     62     int mid=(l+r)/2;
     63     NewNode(x,fa,a[mid]);
     64     build(ch[x][0],l,mid-1,x);
     65     build(ch[x][1],mid+1,r,x);
     66     pushup(x);
     67 }
     68 int getkth(int r,int k)
     69 {
     70     pushdown(r);
     71     int x=size[ch[r][0]]+1;
     72     if (k==x) return r;
     73     if (k<x) getkth(ch[r][0],k);
     74     else getkth(ch[r][1],k-x);
     75 }
     76 void rotate(int x,bool t)
     77 {
     78     int y=pre[x];
     79     pushdown(y);pushdown(x);
     80     ch[y][!t]=ch[x][t];
     81     pre[ch[x][t]]=y;
     82     if (pre[y])
     83       ch[pre[y]][ch[pre[y]][1]==y]=x;
     84       pre[x]=pre[y];
     85       ch[x][t]=y;
     86       pre[y]=x;
     87     pushup(y);
     88 }
     89 void splay(int x,int goal)
     90 {
     91     pushdown(x);
     92     while (pre[x]!=goal)
     93     {
     94         if (pre[pre[x]]==goal)
     95         {
     96             pushdown(pre[x]);
     97             pushdown(x);
     98             rotate(x,ch[pre[x]][0]==x);
     99         }
    100         else
    101         {
    102             pushdown(pre[pre[x]]);
    103             pushdown(pre[x]);
    104             pushdown(x);
    105             int y=pre[x],kind=ch[pre[y]][0]==y;
    106             if (ch[y][kind]==x)
    107             {
    108                 rotate(x,!kind);
    109                 rotate(x,kind);
    110             }
    111             else
    112             {
    113                 rotate(y,kind);
    114                 rotate(x,kind);
    115             }
    116         }
    117     }
    118     pushup(x);
    119     if (goal==0) root=x;
    120 }
    121 void insert(int pos,int tot)
    122 {int i;
    123     for (i=1; i<=tot; i++)
    124     {
    125         a[i]=gi();
    126     }
    127     splay(getkth(root,pos+1),0);
    128     splay(getkth(root,pos+2),root);
    129     build(ch[ch[root][1]][0],1,tot,ch[root][1]);
    130     pushup(ch[root][1]);
    131     pushup(root);
    132 }
    133 void erase(int r)
    134 {
    135     if (!r) return ;
    136     s[++tot2]=r;
    137     erase(ch[r][0]);
    138     erase(ch[r][1]);
    139 }
    140 void Delete(int pos,int tot)
    141 {
    142     splay(getkth(root,pos),0);
    143     splay(getkth(root,pos+tot+1),root);
    144     erase(ch[ch[root][1]][0]);
    145     pre[ch[ch[root][1]][0]]=0;
    146     ch[ch[root][1]][0]=0;
    147     pushup(ch[root][1]);
    148     pushup(root);
    149 }
    150 void update_same(int x,int c)
    151 {
    152     if (!x) return;
    153     key[x]=c;
    154     sum[x]=size[x]*c;
    155     lx[x]=rx[x]=maxsum[x]=max(c,size[x]*c);
    156     same[x]=1;
    157 }
    158 void Make_same(int pos,int tot,int c)
    159 {
    160     splay(getkth(root,pos),0);
    161     splay(getkth(root,pos+tot+1),root);
    162     update_same(ch[ch[root][1]][0],c);
    163     pushup(ch[root][1]);
    164     pushup(root);
    165 }
    166 void update_Reverse(int x)
    167 {
    168     if (!x) return;
    169     swap(ch[x][0],ch[x][1]);
    170     swap(lx[x],rx[x]);
    171     rev[x]^=1;
    172 }
    173 void Reverse(int pos,int tot)
    174 {
    175     splay(getkth(root,pos),0);
    176     splay(getkth(root,pos+tot+1),root);
    177     update_Reverse(ch[ch[root][1]][0]);
    178     pushup(ch[root][1]);
    179     pushup(root);
    180 }
    181 int getsum(int pos,int tot)
    182 {
    183     splay(getkth(root,pos),0);
    184     splay(getkth(root,pos+tot+1),root);
    185     return sum[ch[ch[root][1]][0]];
    186 }
    187 int Max_sum()
    188 {
    189     splay(getkth(root,1),0);
    190     splay(getkth(root,size[root]),root);
    191     return maxsum[ch[ch[root][1]][0]];
    192 }
    193 int main()
    194 {int i,j,x,y,z;
    195  char str[101];
    196     cin>>n>>m;
    197     for (i=1; i<=n; i++)
    198     {
    199         a[i]=gi();
    200     }
    201     lx[root]=rx[root]=maxsum[root]=-2e9;
    202     NewNode(root,0,-1);
    203     NewNode(ch[root][1],root,-1);
    204     build(ch[ch[root][1]][0],1,n,ch[root][1]);
    205     pushup(ch[root][1]);
    206     pushup(root);
    207     for (i=1; i<=m; i++)
    208     {
    209         scanf("%s",str);
    210         if (str[0]=='I')
    211         {
    212             x=gi();y=gi();
    213             insert(x,y);
    214         }
    215         else if (str[0]=='D')
    216         {
    217             x=gi();y=gi();
    218             Delete(x,y);
    219         }
    220         else if (str[0]=='M'&&str[4]=='-')
    221         {
    222             x=gi();y=gi();z=gi();
    223             Make_same(x,y,z);
    224         }
    225         else if (str[0]=='R')
    226         {
    227             x=gi();
    228             y=gi();
    229             Reverse(x,y);
    230         }
    231         else if (str[0]=='G')
    232         {
    233             x=gi();
    234             y=gi();
    235             printf("%d
    ",getsum(x,y));
    236         }
    237         else if (str[0]=='M'&&str[3]=='-')
    238         {
    239             printf("%d
    ",Max_sum());
    240         }
    241     }
    242 }
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    领导满意的高逼格报告,可视化吊打Excel,仅用5步就能教会你
    TTL
    s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 0)
    VSCode的配置和插件同步到多台电脑
    C 语言编程 — 高级数据类型 — void 类型
    C 语言编程 — 高级数据类型 — 字符串
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7203973.html
Copyright © 2011-2022 走看看