bzoj1500 维修序列

OI生涯中印象最深一题 一直被卡0。。

  1 #include<bits/stdc++.h>
  2 #define clr(a,x) memset(a,x,sizeof(a))
  3 #define rep(i,l,r) for(int i=l;i<r;i++)
  4 #define lowbit(a) ((a)&(-(a)))
  5 typedef long long ll;
  6 typedef unsigned long long ul;
  7 using namespace std;
  8 int read(){
  9     int ans=0,f=1;
 10     char c=getchar();
 11     while(!isdigit(c)){
 12         if(c=='-') f=-1;
 13         c=getchar();
 14     }
 15     while(isdigit(c)){
 16         ans=ans*10+c-'0';
 17         c=getchar();
 18     }
 19     return ans*f;
 20 }
 21 const int maxn=550000,inf=1e9;
 22 struct node*null;
 23 struct node{
 24     int v,sum,maxl,maxr,mx,s,set;
 25     bool rev;
 26     node*ch[2];
 27     inline int cmp(int k){
 28         k-=ch[0]->s;
 29         if(k==1) return -1;
 30         return (k<=0)?0:1;
 31     }
 32     inline void maintain(){
 33         s=ch[0]->s+ch[1]->s+1;
 34         sum=ch[0]->sum+ch[1]->sum+v;
 35         maxl=max(ch[0]->maxl,ch[0]->sum+v+max(0,ch[1]->maxl));
 36         maxr=max(ch[1]->maxr,ch[1]->sum+v+max(0,ch[0]->maxr));
 37         mx=max(ch[0]->mx,ch[1]->mx);
 38         mx=max(mx,max(0,ch[0]->maxr)+v+max(0,ch[1]->maxl));
 39     }
 40     inline void Set(int k){
 41         set=k;
 42         v=k;
 43         sum=s*k;
 44         mx=maxl=maxr=k*(k>0?s:1);    
 45     }
 46     inline void Rev(){
 47         rev^=1;
 48         swap(ch[0],ch[1]);
 49         swap(maxl,maxr);
 50     }
 51     inline void pushdown(){
 52         if(set!=inf){
 53             if(ch[0]!=null) ch[0]->Set(set);
 54             if(ch[1]!=null) ch[1]->Set(set);
 55             set=inf;
 56             rev=0;
 57         }
 58         if(rev){
 59             rev=0;
 60             if(ch[0]!=null) ch[0]->Rev();
 61             if(ch[1]!=null) ch[1]->Rev();
 62         }
 63     }
 64 };
 65 int pos,tot,n,m,a[maxn];
 66 node x[maxn],*root;
 67 queue<node*>Q;
 68 node*newnode(int k){
 69     node*o=Q.front();Q.pop();
 70     o->ch[0]=o->ch[1]=null;
 71     o->s=1;
 72     o->set=inf;
 73     o->rev=0;
 74     o->v=o->sum=o->maxl=o->maxr=o->mx=k;
 75     return o;
 76 }
 77 void rot(node*&o,int d){
 78     o->pushdown();
 79     node*k=o->ch[d^1];
 80     k->pushdown();
 81     o->ch[d^1]=k->ch[d];
 82     k->ch[d]=o;
 83     o->maintain();k->maintain();
 84     o=k;
 85 }
 86 void splay(node*&o,int k){
 87     o->pushdown();
 88     int d=o->cmp(k);
 89     if(d==-1) return;
 90     if(d==1) k-=o->ch[0]->s+1;
 91     node*p=o->ch[d];
 92     p->pushdown();
 93     int d1=p->cmp(k);
 94     int k1=(d1)?k-p->ch[0]->s-1:k; 
 95     if(d1!=-1){
 96         splay(p->ch[d1],k1);
 97         (d==d1)?rot(o,d^1):rot(o->ch[d],d);
 98     }
 99     rot(o,d^1);
100 }
101 node*build(int l,int r){
102     if(l>=r) return null;
103     int mid=(l+r)>>1;
104     node*o=newnode(a[mid]);
105     if(l<mid) o->ch[0]=build(l,mid);
106     if(r>mid+1) o->ch[1]=build(mid+1,r);
107     o->maintain();
108     return o;
109 }
110 void ins(){
111     node*o=build(1,tot+1);
112     splay(root,pos+1);
113     splay(root->ch[1],pos+1-root->ch[0]->s);
114     root->ch[1]->ch[0]=o;
115     root->ch[1]->maintain();root->maintain();
116 }
117 void del(node*o){
118     if(o==null) return;
119     del(o->ch[0]);
120     del(o->ch[1]);
121      Q.push(o);
122 }
123 void init(){
124     rep(i,0,maxn) Q.push(x+i);
125     null=newnode(0);
126     null->s=0;
127     null->maxl=null->maxr=null->mx=null->v=-inf; 
128     root=build(0,n+2);
129 }
130 void dfs(node*o){
131     if(o==null) return;
132     o->pushdown();
133     dfs(o->ch[0]);
134     printf("%d ",o->mx);
135     dfs(o->ch[1]);
136 }
137 int main()
138 {    
139     n=read(),m=read();
140     rep(i,1,n+1) a[i]=read();
141     a[0]=a[n+1]=-inf;
142     init();
143     while(m--){
144         char c[15];
145         scanf(" %s",c);
146         if(c[0]=='I'){
147             pos=read(),tot=read();
148             clr(a,0);
149             rep(i,1,tot+1) a[i]=read();
150             ins();
151         }else if(c[0]=='D'){
152             pos=read(),tot=read();
153             splay(root,pos);
154             splay(root->ch[1],pos+tot-root->ch[0]->s);
155             del(root->ch[1]->ch[0]);
156             root->ch[1]->ch[0]=null;
157             root->ch[1]->maintain();root->maintain();
158         }else if(c[0]=='R'){
159             pos=read(),tot=read();
160             splay(root,pos);
161             splay(root->ch[1],pos+tot-root->ch[0]->s);
162             root->ch[1]->ch[0]->Rev();
163             root->ch[1]->maintain();root->maintain();
164         }else if(c[0]=='G'){
165             pos=read(),tot=read();
166             splay(root,pos);
167             splay(root->ch[1],pos+tot-root->ch[0]->s);
168             printf("%d
",root->ch[1]->ch[0]->sum);
169         }else if(c[2]=='K'){
170             pos=read(),tot=read();
171             int t=read();
172             splay(root,pos);
173             splay(root->ch[1],pos+tot-root->ch[0]->s);
174             root->ch[1]->ch[0]->Set(t);
175             root->ch[1]->maintain();root->maintain();
176         }else{
177             printf("%d
",root->mx);
178         }    
179     }
180     return 0;
181 }
View Code

1500: [NOI2005]维修数列

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 8501  Solved: 2563
[Submit][Status][Discuss]

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

Source

原文地址:https://www.cnblogs.com/chensiang/p/4696751.html