wjyi

人这么弱,有什么资格颓废(ಥ _ ಥ)

  博客园  :: 首页  :: 新随笔  :: 联系 ::  :: 管理

未完待续。。。

终于改对了 热泪盈眶.jpg

错误原因:pushdown的时候没有判断是否有左右儿子,也没当x=0 return,于是出现一些奇怪的错误

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define N 500005
  4 char s[10];
  5 int n,m;
  6 int root,fa[N],sz[N],ch[N][2],lc[N],rc[N],num[N],c[N],rev[N],tag[N];
  7 void pushup(int x){
  8   int l=ch[x][0],r=ch[x][1];
  9   sz[x]=sz[l]+sz[r]+1;
 10   num[x]=num[l]+num[r]+1;
 11   lc[x]=rc[x]=c[x];
 12   if(l)num[x]-=rc[l]==c[x],lc[x]=lc[l];
 13   if(r)num[x]-=lc[r]==c[x],rc[x]=rc[r];
 14 }
 15 void pushdown(int x){
 16   if(!x)return;
 17   int l=ch[x][0],r=ch[x][1];
 18   if(tag[x]){
 19     tag[x]=0;  
 20     if(l){  
 21       num[l]=1;tag[l]=1;  
 22       lc[l]=rc[l]=c[l]=c[x];  
 23     }  
 24     if(r){  
 25       num[r]=1;tag[r]=1;  
 26       lc[r]=rc[r]=c[r]=c[x];  
 27     }  
 28   }
 29   if(rev[x]){  
 30     rev[x]^=1;rev[l]^=1;rev[r]^=1;  
 31     if(l){  
 32       swap(lc[l],rc[l]);  
 33       swap(ch[l][0],ch[l][1]);  
 34     }  
 35     if(r){  
 36       swap(lc[r],rc[r]);  
 37       swap(ch[r][0],ch[r][1]);  
 38     }  
 39   }  
 40 }
 41 void rotate(int x){
 42   int y=fa[x],z=fa[y],k=ch[y][1]==x;
 43   fa[ch[y][k]=ch[x][!k]]=y;
 44   fa[ch[x][!k]=y]=x;
 45   fa[x]=z;
 46   if(z)ch[z][ch[z][1]==y]=x;else root=x;
 47   pushup(y);
 48 }
 49 void splay(int x,int f){
 50   pushdown(x);
 51   while(fa[x]!=f){
 52     int y=fa[x],z=fa[y];
 53     pushdown(z);pushdown(y);pushdown(x);
 54     if(z==f)rotate(x);
 55     else{
 56       if((ch[z][1]==y)==(ch[y][1]==x))rotate(y);
 57       else rotate(x);
 58       rotate(x);
 59     }
 60   }
 61   pushup(x);
 62 }
 63 int select(int k,int f){
 64   int x=root;pushdown(x);
 65   while(sz[ch[x][0]]!=k-1){
 66     if(sz[ch[x][0]]>=k)x=ch[x][0];
 67     else k-=sz[ch[x][0]]+1,x=ch[x][1];
 68     pushdown(x);
 69   }
 70   splay(x,f);
 71   return x;
 72 }
 73 void build(int l,int r,int f){
 74   int mid=l+r>>1;
 75   fa[mid]=f;if(mid<f)ch[f][0]=mid;else ch[f][1]=mid;
 76   if(l==r){sz[mid]=1;lc[mid]=rc[mid]=c[mid];num[mid]=1;return;}
 77   if(l<mid)build(l,mid-1,mid);
 78   if(r>mid)build(mid+1,r,mid);
 79   pushup(mid);
 80 }
 81 void change(int k){
 82   int x=select(n-k-1,0),y=select(n,root);
 83   int z=ch[y][0];fa[z]=0;ch[y][0]=0;
 84   pushup(y);pushup(x);
 85   x=select(1,0);y=select(2,root);
 86   ch[y][0]=z;fa[z]=y;
 87   pushup(y);pushup(x);
 88 }
 89 void Flip(){
 90   int x=select(2,0),y=select(n,root);
 91   int z=ch[y][0];
 92   if(tag[z])return;
 93   rev[z]^=1;swap(ch[z][0],ch[z][1]);swap(lc[z],rc[z]);
 94   pushup(y);pushup(x);
 95 }
 96 void Swap(int x,int y){
 97   x=select(x+1,0);
 98   int cx=c[x];
 99   y=select(y+1,0);
100   int cy=c[y];
101   c[y]=cx;pushup(y);
102   splay(x,0);
103   c[x]=cy;pushup(x);
104 }
105 void Paint(int x,int y,int cc){
106   if(x<=y){
107     x=select(x,0);
108     y=select(y+2,root);
109     int z=ch[y][0];
110     tag[z]=1;
111     c[z]=lc[z]=rc[z]=cc;num[z]=1;
112     splay(z,0);
113   }
114   else{
115     change(n-1-x);
116     Paint(1,n-1-x+y,cc);
117     change(x-1);
118   }
119 }
120 int CountSeg(int x,int y){
121   if(x<=y){
122     x=select(x,0);y=select(y+2,root);
123     return num[ch[y][0]];
124   }
125   else{
126     change(n-1-x);
127     int ans=CountSeg(1,n-1-x+y);
128     change(x-1);
129     return ans;
130   }
131 }
132 int Count(){
133   int ans=num[root]-2;
134   int x=select(1,0),y=select(n,root);
135   int z=ch[y][0];
136   ans-=lc[z]==rc[z];
137   return max(ans,1);
138 }
139 int main(){
140   scanf("%d%d",&n,&m);
141   for(int i=2;i<=n+1;i++)scanf("%d",&c[i]);
142   n+=2;build(1,n,0);root=(1+n)>>1;
143   scanf("%d",&m);
144   int x,y,z;
145   while(m--){
146       scanf("%s",s);
147       if(s[0]=='R'){
148         scanf("%d",&x);change(x);
149     }
150       else if(s[0]=='F')Flip();
151       else if(s[0]=='S'){
152         scanf("%d%d",&x,&y);Swap(x,y);
153     }
154       else if(s[0]=='P'){
155         scanf("%d%d%d",&x,&y,&z);
156         Paint(x,y,z);
157       }
158       else if(s[1]=='S'){
159         scanf("%d%d",&x,&y);
160       printf("%d\n",CountSeg(x,y));    
161       }
162       else printf("%d\n",Count());
163   }
164   return 0;
165 }
View Code

 

1493: [NOI2007]项链工厂

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 1320  Solved: 576
[Submit][Status][Discuss]

Description

T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。
最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。该项链自助生产系
统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的
项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能
帮助T公司编写一个软件模拟系统吗?一条项链包含 N 个珠子,每个珠子的颜色是 1,2,…,c 中的一种。项链
被固定在一个平板上,平板的某个位置被标记位置 1 ,按顺时针方向其他位置被记为 2,3,…,N。
你将要编写的软件系统应支持如下命令:

Input

输入文件第一行包含两个整数 N,c ,分别表示项链包含的珠子数目以及颜色数目。
第二行包含 N 个整数,x1,x2,…,xn ,表示从位置 1 到位置 N 的珠子的颜色,1≤xi≤c 。
第三行包含一个整数 Q ,表示命令数目。接下来的 Q 行每行一条命令,如上文所述。N≤500000 ,Q≤500000,c≤1000 
 

Output

对于每一个 C 和 CS 命令,应输出一个整数代表相应的答案。

Sample Input

5 3
1 2 3 2 1
4
C
R 2
P 5 5 2
CS 4 1

Sample Output

4
1

HINT

 

注意旋转命令旋转“珠子”但不改变“位置”的编号,而反转命令始终以位置 1 为对称轴。例如当 N=10 时,项

链上的位置编号如图1:



但注意此时项链上的位置编号仍然如图1所示,于是翻转的对称轴不变。因而再执行一次“F”命令时,项链的颜色

如图4所示。

2. 关于CountSegment命令CS命令表示查询一个“线段”中有多少个“部分”。尤其注意当查询的长度

等于 N 时,我们仍然将查询部分作为“线段”理解。例如在图4所示的情况中,执行“CS 1 10”命令,查询从位

置 1 开始到位置 10 结束的这个长度为 10 的线段中有多少个“部分”,于是得到返回值 3 。与之形成对照的是

,若执行“C”命令,返回值则为 2
posted on 2016-06-25 15:01  wjyi  阅读(206)  评论(0编辑  收藏  举报