数据结构(Splay平衡树): [NOI2007] 项链工厂
Posted 既然选择了远方,便只顾风雨兼程
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构(Splay平衡树): [NOI2007] 项链工厂相关的知识,希望对你有一定的参考价值。
[NOI2007] 项链工厂
★★★ 输入文件:necklace.in
输出文件:necklace.out
简单对比
时间限制:4 s
内存限制:512 MB
【问题描述】
T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。
该项链自助生产系统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能帮助T公司编写一个软件模拟系统吗?
一条项链包含N个珠子,每个珠子的颜色是1, 2, …, c中的一种。项链被固定在一个平板上,平板的某个位置被标记位置1,按顺时针方向其他位置被记为2,3,…,N。
你将要编写的软件系统应支持如下命令:
命令 | 参数限制 | 内容 |
R k | 0 | 意为Rotate k。将项链在平板上顺时针旋转k个位置, 即原来处于位置1的珠子将转至位置k+1,处于位置2的珠子将转至位置k+2,依次类推。 |
F | 意为Flip。将平板沿着给定的对称轴翻转,原来处于位置1的珠子不动,位置2上的珠子与位置N上的珠子互换,位置3上的珠子与位置N-1上的珠子互换,依次类推。 | |
S i j | 1≤i , j≤N | 意为Swap i , j。将位置i上的珠子与位置j上的珠子互换。 |
P i j x | 1≤i , j≤N, x≤c | 意为Paint i , j , x。将位置i沿顺时针方向到位置j的一段染为颜色x。 |
C | 意为Count。查询当前的项链由多少个“部分”组成,我们称项链中颜色相同的一段为一个“部分” | |
CS i j | 1≤i , j≤N | 意为CountSegment i , j。查询从位置i沿顺时针方向到位置j的一段中有多少个部分组成。 |
【输入文件】
输入文件第一行包含两个整数N, c,分别表示项链包含的珠子数目以及颜色数目。第二行包含N个整数,x1, x2…, xn,表示从位置1到位置N的珠子的颜色,1 ≤xi ≤c。第三行包含一个整数Q,表示命令数目。接下来的Q行每行一条命令,如上文所述。
【输出文件】
对于每一个C和CS命令,应输出一个整数代表相应的答案。
【输入样例】
5 3 1 2 3 2 1 4 C R 2 P 5 5 2 CS 4 1
【输出样例】
4 1
【评分方法】
本题没有部分分,你的程序的输出只有和标准答案完全一致才能获得满分, 否则不得分。
【数据规模和约定】
- 对于60%的数据,N ≤1 000,Q ≤1 000;
- 对于100%的数据,N ≤500 000,Q ≤500 000,c ≤1 000。
改了一上午终于AC!
发现自己一直看错题了,Flip指令要以1为中轴,所以1不参与Flip!!!
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int maxn=500010; 6 int ch[maxn][2],fa[maxn],sz[maxn],flip[maxn],mark[maxn]; 7 int key[maxn],tot[maxn],L[maxn],R[maxn],rt; 8 int n,Q,l,r,d,c; 9 char op[10]; 10 void Push_up(int x){ 11 sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; 12 L[x]=ch[x][0]?L[ch[x][0]]:key[x]; 13 R[x]=ch[x][1]?R[ch[x][1]]:key[x]; 14 tot[x]=tot[ch[x][0]]+tot[ch[x][1]]+1; 15 if(ch[x][0]&&R[ch[x][0]]==key[x])tot[x]-=1; 16 if(ch[x][1]&&key[x]==L[ch[x][1]])tot[x]-=1; 17 } 18 19 void Flip(int x){ 20 if(!x)return; 21 swap(ch[x][0],ch[x][1]); 22 swap(L[x],R[x]); 23 flip[x]^=1; 24 } 25 26 void Mark(int x,int d){ 27 if(!x)return; 28 key[x]=L[x]=R[x]=d; 29 tot[x]=1;mark[x]=d; 30 } 31 32 void Push_down(int x){ 33 if(mark[x]!=-1){ 34 Mark(ch[x][0],mark[x]); 35 Mark(ch[x][1],mark[x]); 36 mark[x]=-1; 37 } 38 if(flip[x]){ 39 Flip(ch[x][0]); 40 Flip(ch[x][1]); 41 flip[x]=0; 42 } 43 } 44 45 void Rotate(int x){ 46 int y=fa[x],g=fa[y],c=ch[y][1]==x; 47 ch[y][c]=ch[x][c^1];fa[ch[y][c]]=y; 48 ch[x][c^1]=y;fa[y]=x;fa[x]=g; 49 if(g)ch[g][ch[g][1]==y]=x; 50 Push_up(y); 51 } 52 53 void Splay(int x,int g=0){ 54 for(int y;(y=fa[x])!=g;Rotate(x)) 55 if(fa[y]!=g) 56 Rotate((ch[fa[y]][1]==y)==(ch[y][1]==x)?y:x); 57 Push_up(x); 58 if(!g)rt=x; 59 } 60 61 int Build(int x,int l,int r){ 62 if(l>r)return 0; 63 int mid=(l+r)>>1; 64 ch[mid][0]=Build(mid,l,mid-1); 65 if(mid!=1&&mid!=n+2) 66 scanf("%d",&key[mid]); 67 ch[mid][1]=Build(mid,mid+1,r); 68 sz[mid]=1;mark[mid]=-1; 69 fa[mid]=x;Push_up(mid); 70 return mid; 71 } 72 73 int Get_ID(int k){ 74 int p=rt; 75 while(true){ 76 Push_down(p); 77 if(sz[ch[p][0]]+1==k)break; 78 if(sz[ch[p][0]]+1<k)k-=sz[ch[p][0]]+1,p=ch[p][1]; 79 else p=ch[p][0]; 80 } 81 return p; 82 } 83 84 int main(){ 85 #ifndef ONLINE_JUDGE 86 freopen("necklace.in","r",stdin); 87 freopen("necklace.out","w",stdout); 88 #endif 89 scanf("%d%d",&n,&c); 90 rt=Build(0,1,n+2); 91 scanf("%d",&Q); 92 while(Q--){ 93 scanf("%s",op); 94 if(op[0]==‘R‘){ 95 scanf("%d",&d);d%=n; 96 if(d==0)continue; 97 Splay(Get_ID(n-d+1)); 98 Splay(Get_ID(n+2),rt); 99 int tmp=ch[ch[rt][1]][0]; 100 ch[ch[rt][1]][0]=0; 101 Splay(Get_ID(1)); 102 Splay(Get_ID(2),rt); 103 ch[ch[rt][1]][0]=tmp; 104 fa[tmp]=ch[rt][1]; 105 } 106 else if(op[0]==‘F‘){ 107 Splay(Get_ID(2)); 108 Splay(Get_ID(n+2),rt); 109 Flip(ch[ch[rt][1]][0]); 110 } 111 else if(op[0]==‘S‘){ 112 scanf("%d%d",&l,&r); 113 if(l>r)swap(l,r); 114 if(l==r)continue; 115 Splay(Get_ID(l+1)); 116 Splay(Get_ID(r+1),rt); 117 swap(key[rt],key[ch[rt][1]]); 118 } 119 else if(op[0]==‘P‘){ 120 scanf("%d%d%d",&l,&r,&d); 121 if(l<=r){ 122 Splay(Get_ID(l)); 123 Splay(Get_ID(r+2),rt); 124 Mark(ch[ch[rt][1]][0],d); 125 } 126 else{ 127 Splay(Get_ID(l)); 128 Splay(Get_ID(n+2),rt); 129 Mark(ch[ch[rt][1]][0],d); 130 Splay(Get_ID(1)); 131 Splay(Get_ID(r+2),rt); 132 Mark(ch[ch[rt][1]][0],d); 133 } 134 } 135 else if(op[0]==‘C‘&&op[1]!=‘S‘){ 136 Splay(Get_ID(1)); 137 Splay(Get_ID(n+2),rt); 138 if(L[ch[ch[rt][1]][0]]==R[ch[ch[rt][1]][0]]&&tot[ch[ch[rt][1]][0]]>1) 139 printf("%d\n",tot[ch[ch[rt][1]][0]]-1); 140 else 141 printf("%d\n",tot[ch[ch[rt][1]][0]]); 142 } 143 else if(op[0]==‘C‘&&op[1]==‘S‘){ 144 scanf("%d%d",&l,&r); 145 if(l<=r){ 146 Splay(Get_ID(l)); 147 Splay(Get_ID(r+2),rt); 148 printf("%d\n",tot[ch[ch[rt][1]][0]]); 149 } 150 else{ 151 int ans=0; 152 Splay(Get_ID(l)); 153 Splay(Get_ID(n+2),rt); 154 ans+=tot[ch[ch[rt][1]][0]]; 155 Splay(Get_ID(1)); 156 Splay(Get_ID(r+2),rt); 157 ans+=tot[ch[ch[rt][1]][0]]; 158 Splay(Get_ID(1)); 159 Splay(Get_ID(n+2),rt); 160 if(L[ch[ch[rt][1]][0]]==R[ch[ch[rt][1]][0]]) 161 ans-=1; 162 printf("%d\n",ans); 163 } 164 } 165 } 166 return 0; 167 }
以上是关于数据结构(Splay平衡树): [NOI2007] 项链工厂的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1492: [NOI2007]货币兑换Cash( dp + 平衡树 )
1058. [ZJOI2007]报表统计平衡树-splay+堆