NOI 2005 维修数列

妈妈呀我终于过了!!!原来是数据坑我!!!

弃疗弃疗弃疗弃疗!!!!我调了一天呢。。。。被GET_SUM 8 0打败了。。。。

啥也不说了。。。。还是我太年轻。。。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cstring>
  7 #define PAU putchar(‘ ‘)
  8 #define ENT putchar(‘\n‘)
  9 #define CH for(int d=0;d<=1;d++) if(ch[d])
 10 using namespace std;
 11 const int maxn=500000+10,inf=-1u>>1;
 12 int max(int a,int b,int c){return max(a,max(b,c));}
 13 struct node{
 14     node*fa,*ch[2];
 15     int x;bool rev;int siz,sm,set,lx,rx,mx;
 16     node(){ch[0]=ch[1]=NULL;x=sm=0;lx=rx=mx=-inf;set=inf;rev=false;siz=1;}
 17     void init(){ch[0]=ch[1]=NULL;x=sm=0;lx=rx=mx=-inf;set=inf;rev=false;siz=1;return;}
 18     void revt(){swap(ch[0],ch[1]);swap(lx,rx);rev^=1;return;}
 19     void sett(int tag){x=set=tag;sm=tag*siz;lx=rx=mx=max(tag,tag*siz);return;}
 20     void update();
 21     void down(){
 22         if(rev){CH{ch[d]->revt();}rev=false;}
 23         if(set!=inf){CH{ch[d]->sett(set);}set=inf;}
 24         return;
 25     }
 26 }Splay[maxn],*root;int nodecnt=0;
 27 queue<node*>RAM;
 28 node*newnode(){
 29     node*t;if(!RAM.empty()) t=RAM.front(),RAM.pop();
 30     else t=&Splay[nodecnt++];t->init();return t;
 31 }
 32 void del(node*&x){RAM.push(x);return;}
 33 void deltree(node*&x){
 34     if(!x)return;deltree(x->ch[0]);deltree(x->ch[1]);del(x);return;
 35 }
 36 void copy(node*&x,node*y){
 37     x->x=y->x;
 38     x->lx=y->lx;
 39     x->mx=y->mx;
 40     x->rx=y->rx;
 41     x->sm=y->sm;
 42     x->siz=y->siz;
 43     x->set=y->set;
 44     x->rev=y->rev;
 45     return;
 46 }
 47 void node::update(){
 48     siz=1;sm=x;lx=mx=rx=0;node*n[2];n[0]=newnode();n[1]=newnode();
 49     CH{siz+=ch[d]->siz;sm+=ch[d]->sm;copy(n[d],ch[d]);}
 50     lx=max(n[0]->lx,n[0]->sm+x+max(0,n[1]->lx));
 51     rx=max(n[1]->rx,n[1]->sm+x+max(0,n[0]->rx));
 52     mx=max(0,n[0]->rx)+x+max(0,n[1]->lx);
 53     mx=max(n[0]->mx,n[1]->mx,mx);
 54     del(n[0]);del(n[1]);
 55     return;
 56 }
 57 int parent(node*x,node*&y){return (y=x->fa)?y->ch[1]==x?1:y->ch[0]==x?0:-1:-1;}
 58 void rotate(node*x){
 59     node*y,*z;int d1=parent(x,y),d2=parent(y,z);
 60     if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y;
 61     y->fa=x;x->fa=z;x->ch[d1^1]=y;
 62     if(d2!=-1) z->ch[d2]=x;
 63     y->update();return;
 64 }
 65 void pushdown(node*x){
 66     static node*s[maxn];int top=0;
 67     for(node*y;;x=y){
 68         s[top++]=x;y=x->fa;
 69         if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break;
 70     } while(top--) s[top]->down();return;
 71 }
 72 node*splay(node*x){
 73     pushdown(x);node*y,*z;int d1,d2;
 74     while(true){
 75         if((d1=parent(x,y))<0) break;
 76         if((d2=parent(y,z))<0){rotate(x);break;}
 77         if(d1==d2) rotate(y),rotate(x);
 78         else rotate(x),rotate(x);
 79     } x->update();return x;
 80 }
 81 node*find(node*x,int rank){
 82     x->down();int kth=1;if(x->ch[0]) kth=x->ch[0]->siz+1;
 83     if(rank==kth) return x;
 84     if(rank<kth) return find(x->ch[0],rank);
 85     else return find(x->ch[1],rank-kth);
 86 }
 87 void split(node*&x,node*&y,int a){
 88     if(!a){y=x;x=NULL;return;}
 89     x=splay(find(x,a));y=x->ch[1];
 90     x->ch[1]=NULL;if(y)y->fa=NULL;x->update();return;
 91 }
 92 void split(node*&x,node*&y,node*&z,int a,int b){
 93     split(x,z,b);split(x,y,a-1);return;
 94 }
 95 void join(node*&x,node*y){
 96     if(!x){x=y;return;}if(!y)return;
 97     x=splay(find(x,x->siz));x->ch[1]=y;
 98     if(y)y->fa=x;x->update();return;
 99 }
100 void join(node*&x,node*y,node*z){
101     join(y,z);join(x,y);return;
102 }
103 inline int read(){
104     int x=0,sig=1;char ch=getchar();
105     while(!isdigit(ch)){if(ch==‘-‘)sig=-1;ch=getchar();}
106     while(isdigit(ch))x=10*x+ch-‘0‘,ch=getchar();
107     return x*sig;
108 }
109 inline void write(int x){
110     if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x;
111     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
112     for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return;
113 }
114 int s[maxn];
115 void build(node*&x,int L,int R){
116     if(L>R)return;int M=L+R>>1;
117     x=newnode();x->x=s[M];
118     build(x->ch[0],L,M-1);
119     build(x->ch[1],M+1,R);
120     if(x->ch[0]) x->ch[0]->fa=x;
121     if(x->ch[1]) x->ch[1]->fa=x;
122     x->update();return;
123 }
124 void insert(int pos,int num){
125     int ms=0;for(int i=0;i<num;i++) s[ms++]=read();
126     node*x,*y;build(x,0,num-1);
127     split(root,y,pos);join(root,x,y);return;
128 }
129 void remove(int L,int R){
130     node*x,*y;split(root,x,y,L,R);deltree(x);join(root,y);return;
131 }
132 void settag(int L,int R,int tag){
133     node*x,*y;split(root,x,y,L,R);x->sett(tag);join(root,x,y);return;
134 }
135 int getsum(int L,int R){
136     node*x,*y;split(root,x,y,L,R);int sm=x->sm;join(root,x,y);return sm;
137 }
138 int getssm(int L,int R){
139     node*x,*y;split(root,x,y,L,R);int mx=x->mx;join(root,x,y);return mx;
140 }
141 void reverse(int L,int R){
142     node*x,*y;split(root,x,y,L,R);x->revt();join(root,x,y);return;
143 }
144 void init(){
145     int n,Q;int pos,k,v;char str[15];
146     while(scanf("%d%d",&n,&Q)==2){
147         for(int i=0;i<n;i++) s[i]=read();build(root,0,n-1);
148         while(Q--){
149             scanf("%s",str);
150             if(str[0]==‘I‘){
151                 pos=read();k=read();
152                 insert(pos,k);
153             }
154             else if(str[0]==‘D‘){
155                 pos=read();k=read();
156                 remove(pos,pos+k-1);
157             }
158             else if(!strcmp(str,"MAKE-SAME")){
159                 pos=read();k=read();v=read();
160                 settag(pos,pos+k-1,v);
161             }
162             else if(!strcmp(str,"REVERSE")){
163                 pos=read();k=read();
164                 reverse(pos,pos+k-1);
165             }
166             else if(!strcmp(str,"GET-SUM")){
167                 pos=read();k=read();
168                 if(!k){puts("0");continue;}
169                 write(getsum(pos,pos+k-1));ENT;
170             }
171             else write(getssm(1,root->siz)),ENT;
172         } deltree(root);
173     }
174     return;
175 }
176 void work(){
177     return;
178 }
179 void print(){
180     return;
181 }
182 int main(){init();work();print();return 0;}
时间: 2024-07-28 15:34:00

NOI 2005 维修数列的相关文章

BZOJ 1500 NOI 2005 维修数列 Splay

题意:见下图 传说级别的NOI数据结构神题,像我这种弱渣花了一下午的时间才A掉,最后发现竟然是边界值的问题没处理好.. 这个题对Splay的所有操作基本是全了. 插入:新建一颗Splay Tree,然后把对应节点Splay到根的右儿子上,再把新建的树连上. 删除:把要删除的区间Splay到根的右儿子的左儿子上,递归free掉.(这里可以用数组优化,可以避免递归free节省时间) 修改,翻转:打标记,在需要的时候下传标记,和线段树差不多,翻转标记下传时,要将左右儿子的左右儿子分别交换. 求和:维护

bzoj 1500 [NOI 2005] 维修数列

题目大意不多说了 貌似每个苦逼的acmer都要做一下这个splay树的模版题目吧 还是有很多操作的,估计够以后当模版了.... 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 7 using namespace std; 8 const int N = 1000010; 9 cons

noi 2005维修数列

OI生涯中最想过的一题=v= splay加上各种各样的操作,样例又不敢拿来调了... 感觉指针写splay好难调,所以以后写splay都用数组吧(其实是因为黄大神也用数组orz) 好像是2小时敲完..debug了2天TAT一开始把操作6和某提混了... 然后搞来搞去才发现读入有个毛病0A0 再然后又发现一直以来自己的pushdown和别人是不一样的..(那些题我居然过了...) 最后被内存限制卡住,时间换空间..(然而本地测试90...难道是我的电脑太慢?) 虽然很累,但学了不少,值了 1 #i

NOI 2005维护数列

题目描述 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格) 输入输出格式 输入格式: 输入文件的第 1 行包含两个数 N 和 M,N 表示初始时数列中数的个数,M 表示要进行的操作数目. 第 2 行包含 N 个数字,描述初始时的数列. 以下 M 行,每行一条命令,格式参见问题描述中的表格 输出格式: 对于输入数据中的 GET-SUM 和 MAX-SUM 操作,向输出文件依次打印结 果,每个答案(数字)占一行. SOL: 我们发

1500: [NOI2005]维修数列

1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 12952  Solved: 4138[Submit][Status][Discuss] Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的表格.任何时刻数列中最多含有500 000个数,

BZOJ1500: [NOI2005]维修数列[splay ***]

1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 12278  Solved: 3880[Submit][Status][Discuss] Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的表格.任何时刻数列中最多含有500 000个数,

BZOJ 1500: [NOI2005]维修数列

1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 12880  Solved: 4112[Submit][Status][Discuss] Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的表格.任何时刻数列中最多含有500 000个数,

BZOJ1500 维修数列

1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MB Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的表格.任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内.插入的数字总数不超过4 000 000个,输入文

bzoj1500 维修数列 splay

1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 10482  Solved: 3234[Submit][Status][Discuss] Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的表格.任何时刻数列中最多含有500 000个数,