未完待续。。。
终于改对了 热泪盈眶.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 }
1493: [NOI2007]项链工厂
Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 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
1 2 3 2 1
4
C
R 2
P 5 5 2
CS 4 1
Sample Output
4
1
1
HINT
注意旋转命令旋转“珠子”但不改变“位置”的编号,而反转命令始终以位置 1 为对称轴。例如当 N=10 时,项
链上的位置编号如图1:
但注意此时项链上的位置编号仍然如图1所示,于是翻转的对称轴不变。因而再执行一次“F”命令时,项链的颜色
如图4所示。
2. 关于CountSegment命令CS命令表示查询一个“线段”中有多少个“部分”。尤其注意当查询的长度
等于 N 时,我们仍然将查询部分作为“线段”理解。例如在图4所示的情况中,执行“CS 1 10”命令,查询从位
置 1 开始到位置 10 结束的这个长度为 10 的线段中有多少个“部分”,于是得到返回值 3 。与之形成对照的是
,若执行“C”命令,返回值则为 2