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\n",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\n",root->mx); 178 } 179 } 180 return 0; 181 }
1500: [NOI2005]维修数列
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 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
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
10
1
10
HINT