记录编号 360820 评测结果 AAAAAAAAAA
题目名称 [NOI 2005]维护数列 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 2.581 s
提交时间 2017-01-01 16:10:46 内存使用 19.38 MiB
显示代码纯文本
  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #define dir(x) ((int)((x)==(x)->p->ch[1]))
  5. using namespace std;
  6. struct node{
  7. int data,size,sum,prefix,suffix,maxsum;
  8. bool rev,same;
  9. node *ch[2],*p;
  10. node(int d):data(d),size(1),sum(d),prefix(d),suffix(d),maxsum(d),rev(false),same(false){}
  11. void reverse(){
  12. if(data==-1000000)return;
  13. rev^=true;
  14. swap(prefix,suffix);
  15. }
  16. void makesame(int d){
  17. if(data==-1000000)return;
  18. data=d;
  19. sum=d*size;
  20. prefix=suffix=maxsum=max(sum,d);
  21. same=true;
  22. }
  23. void pushdown(){
  24. if(rev){
  25. ch[0]->reverse();
  26. ch[1]->reverse();
  27. swap(ch[0],ch[1]);
  28. rev=false;
  29. }
  30. if(same){
  31. ch[0]->makesame(data);
  32. ch[1]->makesame(data);
  33. same=false;
  34. }
  35. }
  36. void refresh(){
  37. size=ch[0]->size+ch[1]->size+1;
  38. sum=ch[0]->sum+ch[1]->sum+data;
  39. prefix=max(ch[0]->prefix,ch[0]->sum+data+max(ch[1]->prefix,0));
  40. suffix=max(ch[1]->suffix,ch[1]->sum+data+max(ch[0]->suffix,0));
  41. maxsum=max(max(ch[0]->maxsum,ch[1]->maxsum),max(ch[0]->suffix,0)+data+max(ch[1]->prefix,0));
  42. }
  43. }*null=new node(-1000000),*root=null;
  44. void insert(int,int);
  45. void erase(int,int);
  46. void makesame(int,int,int);
  47. void reverse(int,int);
  48. int getsum(int,int);
  49. int maxsum();
  50. node *build(int,int);
  51. void removetree(node*);
  52. node *kth(int);
  53. void splay(node*,node*);
  54. void rot(node*,int);
  55. int n,m,pos,cnt,d,a[5000010];
  56. char c[15];
  57. int main(){
  58. freopen("seq2005.in","r",stdin);
  59. freopen("seq2005.out","w",stdout);
  60. null->ch[0]=null->ch[1]=null->p=null;
  61. null->size=null->sum=0;
  62. scanf("%d%d",&n,&m);
  63. insert(0,n);//dfs(root);
  64. while(m--){
  65. scanf("%s",c);
  66. if(!strcmp(c,"INSERT")){
  67. scanf("%d%d",&pos,&cnt);
  68. insert(pos,cnt);
  69. }
  70. else if(!strcmp(c,"DELETE")){
  71. scanf("%d%d",&pos,&cnt);
  72. erase(pos,cnt);
  73. }
  74. else if(!strcmp(c,"MAKE-SAME")){
  75. scanf("%d%d%d",&pos,&cnt,&d);
  76. makesame(pos,cnt,d);
  77. }
  78. else if(!strcmp(c,"REVERSE")){
  79. scanf("%d%d",&pos,&cnt);
  80. reverse(pos,cnt);
  81. }
  82. else if(!strcmp(c,"GET-SUM")){
  83. scanf("%d%d",&pos,&cnt);
  84. printf("%d\n",getsum(pos,cnt));
  85. }
  86. else if(!strcmp(c,"MAX-SUM"))printf("%d\n",maxsum());
  87. }
  88. return 0;
  89. }
  90. node *newnode(int d){
  91. node *x=new node(d);
  92. x->ch[0]=x->ch[1]=x->p=null;
  93. return x;
  94. }
  95. void insert(int pos,int cnt){
  96. for(int i=1;i<=cnt;i++)scanf("%d",&a[i]);
  97. node *x=build(1,cnt);
  98. if(root==null){
  99. root=x;
  100. return;
  101. }
  102. if(!pos){
  103. splay(kth(1),null);
  104. root->ch[0]=x;
  105. x->p=root;
  106. root->refresh();
  107. }
  108. else if(pos==root->size){
  109. splay(kth(root->size),null);
  110. root->ch[1]=x;
  111. x->p=root;
  112. root->refresh();
  113. }
  114. else{
  115. splay(kth(pos),null);
  116. splay(kth(pos+1),root);
  117. root->ch[1]->ch[0]=x;
  118. x->p=root->ch[1];
  119. root->ch[1]->refresh();
  120. root->refresh();
  121. }
  122. }
  123. void erase(int pos,int cnt){
  124. if(cnt==root->size){
  125. removetree(root);
  126. root=null;
  127. return;
  128. }
  129. if(pos==1){
  130. splay(kth(cnt+1),null);
  131. removetree(root->ch[0]);
  132. root->ch[0]=null;
  133. root->refresh();
  134. }
  135. else if(pos+cnt-1==root->size){
  136. splay(kth(pos-1),null);
  137. removetree(root->ch[1]);
  138. root->ch[1]=null;
  139. root->refresh();
  140. }
  141. else{
  142. splay(kth(pos-1),null);
  143. splay(kth(pos+cnt),root);
  144. removetree(root->ch[1]->ch[0]);
  145. root->ch[1]->ch[0]=null;
  146. root->ch[1]->refresh();
  147. root->refresh();
  148. }
  149. }
  150. void makesame(int pos,int cnt,int d){
  151. if(cnt==root->size)root->makesame(d);
  152. else if(pos==1){
  153. splay(kth(cnt+1),null);
  154. root->ch[0]->makesame(d);
  155. root->refresh();
  156. }
  157. else if(pos+cnt-1==root->size){
  158. splay(kth(pos-1),null);
  159. root->ch[1]->makesame(d);
  160. root->refresh();
  161. }
  162. else{
  163. splay(kth(pos-1),null);
  164. splay(kth(pos+cnt),root);
  165. root->ch[1]->ch[0]->makesame(d);
  166. root->ch[1]->refresh();
  167. root->refresh();
  168. }
  169. }
  170. void reverse(int pos,int cnt){
  171. if(cnt==root->size)root->reverse();
  172. else if(pos==1){
  173. splay(kth(cnt+1),null);
  174. root->ch[0]->reverse();
  175. root->refresh();
  176. }
  177. else if(pos+cnt-1==root->size){
  178. splay(kth(pos-1),null);
  179. root->ch[1]->reverse();
  180. root->refresh();
  181. }
  182. else{
  183. splay(kth(pos-1),null);
  184. splay(kth(pos+cnt),root);
  185. root->ch[1]->ch[0]->reverse();
  186. root->ch[1]->refresh();
  187. root->refresh();
  188. }
  189. }
  190. int getsum(int pos,int cnt){
  191. if(!cnt)return 0;
  192. if(cnt==root->size)return root->sum;
  193. else if(pos==1){
  194. splay(kth(cnt+1),null);
  195. return root->ch[0]->sum;
  196. }
  197. else if(pos+cnt-1==root->size){
  198. splay(kth(pos-1),null);
  199. return root->ch[1]->sum;
  200. }
  201. else{
  202. splay(kth(pos-1),null);
  203. splay(kth(pos+cnt),root);
  204. return root->ch[1]->ch[0]->sum;
  205. }
  206. }
  207. int maxsum(){
  208. if(root==null)return 0;
  209. root->pushdown();
  210. return root->maxsum;
  211. }
  212. node *build(int l,int r){
  213. if(l>r)return null;
  214. int mid=(l+r)>>1;
  215. node *x=newnode(a[mid]);
  216. if((x->ch[0]=build(l,mid-1))!=null)x->ch[0]->p=x;
  217. if((x->ch[1]=build(mid+1,r))!=null)x->ch[1]->p=x;
  218. x->refresh();
  219. return x;
  220. }
  221. void removetree(node *x){
  222. if(x==null)return;
  223. removetree(x->ch[0]);
  224. removetree(x->ch[1]);
  225. delete x;
  226. }
  227. node *kth(int k){
  228. node *rt=root;
  229. int d;
  230. while(rt){
  231. rt->pushdown();
  232. if(k==rt->ch[0]->size+1)return rt;
  233. if((d=k>rt->ch[0]->size))k-=rt->ch[0]->size+1;
  234. rt=rt->ch[d];
  235. }
  236. return null;
  237. }
  238. void splay(node *x,node *tar){
  239. while(x->p!=tar){
  240. if(x->p->p==tar){
  241. rot(x->p,dir(x)^1);
  242. break;
  243. }
  244. if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
  245. else rot(x->p,dir(x)^1);
  246. rot(x->p,dir(x)^1);
  247. }
  248. }
  249. void rot(node *x,int d){
  250. node *y=x->ch[d^1];
  251. x->ch[d^1]=y->ch[d];
  252. if(y->ch[d]!=null)y->ch[d]->p=x;
  253. y->p=x->p;
  254. if(x->p!=null)x->p->ch[dir(x)]=y;
  255. else root=y;
  256. y->ch[d]=x;
  257. x->p=y;
  258. x->refresh();
  259. y->refresh();
  260. }