您的位置:首页 > 理论基础 > 数据结构算法

数据结构(Splay平衡树): [NOI2007] 项链工厂

2016-06-04 11:02 363 查看

[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!!!

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=500010;
int ch[maxn][2],fa[maxn],sz[maxn],flip[maxn],mark[maxn];
int key[maxn],tot[maxn],L[maxn],R[maxn],rt;
int n,Q,l,r,d,c;
char op[10];
void Push_up(int x){
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
L[x]=ch[x][0]?L[ch[x][0]]:key[x];
R[x]=ch[x][1]?R[ch[x][1]]:key[x];
tot[x]=tot[ch[x][0]]+tot[ch[x][1]]+1;
if(ch[x][0]&&R[ch[x][0]]==key[x])tot[x]-=1;
if(ch[x][1]&&key[x]==L[ch[x][1]])tot[x]-=1;
}

void Flip(int x){
if(!x)return;
swap(ch[x][0],ch[x][1]);
swap(L[x],R[x]);
flip[x]^=1;
}

void Mark(int x,int d){
if(!x)return;
key[x]=L[x]=R[x]=d;
tot[x]=1;mark[x]=d;
}

void Push_down(int x){
if(mark[x]!=-1){
Mark(ch[x][0],mark[x]);
Mark(ch[x][1],mark[x]);
mark[x]=-1;
}
if(flip[x]){
Flip(ch[x][0]);
Flip(ch[x][1]);
flip[x]=0;
}
}

void Rotate(int x){
int y=fa[x],g=fa[y],c=ch[y][1]==x;
ch[y][c]=ch[x][c^1];fa[ch[y][c]]=y;
ch[x][c^1]=y;fa[y]=x;fa[x]=g;
if(g)ch[g][ch[g][1]==y]=x;
Push_up(y);
}

void Splay(int x,int g=0){
for(int y;(y=fa[x])!=g;Rotate(x))
if(fa[y]!=g)
Rotate((ch[fa[y]][1]==y)==(ch[y][1]==x)?y:x);
Push_up(x);
if(!g)rt=x;
}

int Build(int x,int l,int r){
if(l>r)return 0;
int mid=(l+r)>>1;
ch[mid][0]=Build(mid,l,mid-1);
if(mid!=1&&mid!=n+2)
scanf("%d",&key[mid]);
ch[mid][1]=Build(mid,mid+1,r);
sz[mid]=1;mark[mid]=-1;
fa[mid]=x;Push_up(mid);
return mid;
}

int Get_ID(int k){
int p=rt;
while(true){
Push_down(p);
if(sz[ch[p][0]]+1==k)break;
if(sz[ch[p][0]]+1<k)k-=sz[ch[p][0]]+1,p=ch[p][1];
else p=ch[p][0];
}
return p;
}

int main(){
#ifndef ONLINE_JUDGE
freopen("necklace.in","r",stdin);
freopen("necklace.out","w",stdout);
#endif
scanf("%d%d",&n,&c);
rt=Build(0,1,n+2);
scanf("%d",&Q);
while(Q--){
scanf("%s",op);
if(op[0]=='R'){
scanf("%d",&d);d%=n;
if(d==0)continue;
Splay(Get_ID(n-d+1));
Splay(Get_ID(n+2),rt);
int tmp=ch[ch[rt][1]][0];
ch[ch[rt][1]][0]=0;
Splay(Get_ID(1));
Splay(Get_ID(2),rt);
ch[ch[rt][1]][0]=tmp;
fa[tmp]=ch[rt][1];
}
else if(op[0]=='F'){
Splay(Get_ID(2));
Splay(Get_ID(n+2),rt);
Flip(ch[ch[rt][1]][0]);
}
else if(op[0]=='S'){
scanf("%d%d",&l,&r);
if(l>r)swap(l,r);
if(l==r)continue;
Splay(Get_ID(l+1));
Splay(Get_ID(r+1),rt);
swap(key[rt],key[ch[rt][1]]);
}
else if(op[0]=='P'){
scanf("%d%d%d",&l,&r,&d);
if(l<=r){
Splay(Get_ID(l));
Splay(Get_ID(r+2),rt);
Mark(ch[ch[rt][1]][0],d);
}
else{
Splay(Get_ID(l));
Splay(Get_ID(n+2),rt);
Mark(ch[ch[rt][1]][0],d);
Splay(Get_ID(1));
Splay(Get_ID(r+2),rt);
Mark(ch[ch[rt][1]][0],d);
}
}
else if(op[0]=='C'&&op[1]!='S'){
Splay(Get_ID(1));
Splay(Get_ID(n+2),rt);
if(L[ch[ch[rt][1]][0]]==R[ch[ch[rt][1]][0]]&&tot[ch[ch[rt][1]][0]]>1)
printf("%d\n",tot[ch[ch[rt][1]][0]]-1);
else
printf("%d\n",tot[ch[ch[rt][1]][0]]);
}
else if(op[0]=='C'&&op[1]=='S'){
scanf("%d%d",&l,&r);
if(l<=r){
Splay(Get_ID(l));
Splay(Get_ID(r+2),rt);
printf("%d\n",tot[ch[ch[rt][1]][0]]);
}
else{
int ans=0;
Splay(Get_ID(l));
Splay(Get_ID(n+2),rt);
ans+=tot[ch[ch[rt][1]][0]];
Splay(Get_ID(1));
Splay(Get_ID(r+2),rt);
ans+=tot[ch[ch[rt][1]][0]];
Splay(Get_ID(1));
Splay(Get_ID(n+2),rt);
if(L[ch[ch[rt][1]][0]]==R[ch[ch[rt][1]][0]])
ans-=1;
printf("%d\n",ans);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: