• 【BZOJ1500】[NOI2005]维修数列


    Description

    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

    HINT

     
    spaly裸题,但依旧不敢保证自己能写出来,并且有很多不会的地方
      1 #include<queue>
      2 #include<cmath>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<cstdlib>
      6 #include<iostream>
      7 #include<algorithm>
      8 #define inf 1000000000
      9 #define N 1000005
     10 using namespace std;
     11 queue<int> q;
     12 int n,m,rt,sz;
     13 int a[N],id[N],fa[N],c[N][2];
     14 int sum[N],size[N],v[N],mx[N],lx[N],rx[N];
     15 bool tag[N],rev[N];
     16 void updata(int x){
     17     int l=c[x][0],r=c[x][1];
     18     sum[x]=sum[l]+sum[r]+v[x];
     19     size[x]=size[l]+size[r]+1;
     20     mx[x]=max(mx[l],mx[r]);
     21     mx[x]=max(mx[x],rx[l]+v[x]+lx[r]);
     22     lx[x]=max(lx[l],sum[l]+v[x]+lx[r]);//?
     23     rx[x]=max(rx[r],sum[r]+v[x]+rx[l]);
     24 }
     25  
     26 void pushdown(int x){
     27     int l=c[x][0],r=c[x][1];
     28     if (tag[x]){ 
     29         rev[x]=tag[x]=0;
     30         if (l)tag[l]=1,v[l]=v[x],sum[l]=v[x]*size[l];
     31         if (r)tag[r]=1,v[r]=v[x],sum[r]=v[x]*size[r]; 
     32         if (v[x]>=0){
     33             if (l)lx[l]=rx[l]=mx[l]=sum[l];
     34             if (r)lx[r]=rx[r]=mx[r]=sum[r];
     35         }
     36         else {
     37             if (l)lx[l]=rx[l]=0,mx[l]=v[l];
     38             if (r)lx[r]=rx[r]=0,mx[r]=v[r];
     39         }
     40     }
     41     if (rev[x]){
     42         rev[x]^=1;rev[l]^=1;rev[r]^=1;
     43         swap(lx[l],rx[l]);swap(lx[r],rx[r]);
     44         swap(c[l][0],c[l][1]);swap(c[r][0],c[r][1]);//?
     45     }
     46 } 
     47 void rotate(int x,int &k){
     48     int l,r,y=fa[x],z=fa[y];
     49     if (c[y][0]==x) l=0;else l=1;r=l^1;
     50     if (y==k)k=x;
     51     else {if (c[z][0]==y) c[z][0]=x;else c[z][1]=x;}
     52     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
     53     c[y][l]=c[x][r];c[x][r]=y;
     54     updata(y);updata(x); 
     55 }
     56  
     57 void splay(int x,int &k){
     58     while (x!=k){
     59         int y=fa[x],z=fa[y];
     60         if (y!=k){
     61             if ((c[z][0]==y)^(c[y][0]==x)) rotate(x,k);
     62             else rotate(y,k);
     63         }
     64         rotate(x,k);
     65     }
     66 }
     67  
     68 int find(int k,int rk){
     69     pushdown(k);
     70     int l=c[k][0],r=c[k][1];
     71     if (size[l]+1==rk) return k;
     72     if (size[l]>=rk) return find(l,rk);
     73     return find(r,rk-size[l]-1);
     74 }
     75  
     76 int split(int k,int tot){
     77     int x=find(rt,k),y=find(rt,k+tot+1);
     78     splay(x,rt);splay(y,c[x][1]);
     79     return c[y][0];
     80 }
     81  
     82 void build(int l,int r,int f){
     83     if (l>r) return;
     84     int mid=(l+r)>>1,last=id[f],now=id[mid];
     85     if (l==r){
     86         sum[now]=a[l];size[now]=1;
     87         tag[now]=rev[now]=0;
     88         if (a[l]>=0) lx[now]=rx[now]=mx[now]=a[l];
     89         else lx[now]=rx[now]=0,mx[now]=a[l];
     90     }
     91     else build(l,mid-1,mid),build(mid+1,r,mid);
     92     v[now]=a[mid];fa[now]=last;updata(now);
     93     c[last][mid>=f]=now;
     94 }
     95 void insert(int k,int tot){
     96     for (int i=1;i<=tot;i++){
     97         if(!q.empty())id[i]=q.front(),q.pop();
     98         else id[i]=++sz;
     99         scanf("%d",&a[i]);
    100     }
    101     build(1,tot,0);int z=id[(1+tot)>>1];
    102     int x=find(rt,k+1),y=find(rt,k+2);
    103     splay(x,rt);splay(y,c[x][1]);
    104     c[y][0]=z;fa[z]=y;
    105     updata(y);updata(x);
    106 }
    107  
    108 void rec(int x){
    109     if (!x) return;
    110     int l=c[x][0],r=c[x][1];
    111     rec(l);rec(r);q.push(x);
    112     fa[x]=c[x][0]=c[x][1]=tag[x]=rev[x]=0;
    113 }
    114  
    115 void erase(int k,int tot){
    116     int x=split(k,tot),y=fa[x];
    117     rec(x);c[y][0]=0;
    118     updata(y);updata(fa[y]);
    119 }
    120  
    121 void modify(int k,int tot,int val){
    122     int x=split(k,tot),y=fa[x];
    123     v[x]=val;tag[x]=1;sum[x]=size[x]*val;
    124     if (val>=0)lx[x]=rx[x]=mx[x]=sum[x];
    125     else lx[x]=rx[x]=0,mx[x]=val;
    126     updata(y);updata(fa[y]);
    127 }
    128  
    129 void rever(int k,int tot){
    130     int x=split(k,tot),y=fa[x];
    131     if (!tag[x]){//或许会节省一点时间 
    132         rev[x]^=1;
    133         swap(c[x][0],c[x][1]);
    134         swap(lx[x],rx[x]);
    135         updata(y);updata(fa[y]);
    136     }
    137 }
    138  
    139 void query(int k,int tot){
    140     int x=split(k,tot);
    141     printf("%d
    ",sum[x]);
    142 }
    143  
    144 int main(){
    145     scanf("%d%d",&n,&m);
    146     mx[0]=a[1]=a[n+2]=-inf;
    147     for(int i=1;i<=n;i++)scanf("%d",&a[i+1]);
    148     for(int i=1;i<=n+2;i++)id[i]=i;
    149     build(1,n+2,0);
    150     rt=(n+3)>>1;sz=n+2;
    151     int k,tot,val;
    152     char ch[10];
    153     while(m--)
    154     {   //printf("%d
    ",mx[rt]);
    155         scanf("%s",ch);
    156         if(ch[0]!='M'||ch[2]!='X')scanf("%d%d",&k,&tot);
    157         if(ch[0]=='I')insert(k,tot);
    158         if(ch[0]=='D')erase(k,tot);
    159         if(ch[0]=='M')
    160         {
    161             if(ch[2]=='X')printf("%d
    ",mx[rt]);
    162             else scanf("%d",&val),modify(k,tot,val);
    163         }
    164         if(ch[0]=='R')rever(k,tot);
    165         if(ch[0]=='G')query(k,tot);
    166     }
    167     return 0;
    168 }
  • 相关阅读:
    cad 画图面板的尺寸大小定义
    CAD中如何将图形按一定的比例放大或缩小
    数组模拟栈和队列
    41. 缺失的第一个正数
    98. 验证二叉搜索树
    1220. 统计元音字母序列的数目
    网络编程--select模型(总结)
    网络编程--C/S模型(总结)
    C++内存管理(堆栈内存的区别、==和equal的区别)
    condition_variable-介绍和使用
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5154164.html
Copyright © 2020-2023  润新知