1493: [NOI2007]项链工厂
Time Limit: 30 Sec Memory Limit: 64 MB
Submit: 1839 Solved: 762
[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
写之前突然想到可以开两倍数组啊!
于是欢乐的做出了有史以来最错误的一个决定
数据结构反人类啊啊啊啊啊啊啊啊啊
然后我还是意志坚定的把我两倍数组的蜜汁程序写完了?↓
#include<iostream>
#include<cstdio>
using namespace std;
int i,m,n,j,ss,d[3000001],c[500010],zl[3000001],zr[3000001],b,g,h,lazy[3000001],x,y;
char ch[100];
void update(int now)
{
d[now]=d[now*2]+d[now*2+1];
if(zr[now*2]==zl[now*2+1]) d[now]-=1;
zl[now]=zl[now*2], zr[now]=zr[now*2+1];
}
void down(int now)
{
if(!lazy[now]) return ;
lazy[now*2]= lazy[now*2+1]= lazy[now];
d[now*2]=d[now*2+1]=1; d[now]=1;
zl[now*2]=zr[now*2]=zl[now*2+1]=zr[now*2+1]=lazy[now];
lazy[now]=0;
}
void built(int now,int l,int r)
{
if(l==r)
{
int w=l; if(w>n) w-=n;
zl[now]=zr[now]=c[w];
d[now]=1;
return ;
}
int mid=(l+r)>>1;
built(now*2,l,mid);
built(now*2+1,mid+1,r);
update(now);
}
int find(int now,int l,int r,int w)
{
if(l==r) return zr[now];
int mid=(l+r)>>1; down(now);
if(w>mid) return find(now*2+1,mid+1,r,w);
else return find(now*2,l,mid,w);
}
void gai(int now,int l,int r,int w,int z)
{
if(l==r)
{
d[now]=1;
zr[now]=zl[now]=z;
return ;
}
int mid=(l+r)>>1;
down(now);
if(w<=mid) gai(now*2,l,mid,w,z);
else gai(now*2+1,mid+1,r,w,z);
update(now);
}
void modify(int now,int l,int r,int ll,int rr,int z)
{
if(l>=ll && r<=rr)
{
lazy[now]=zl[now]=zr[now]=z;
d[now]=1; return ;
}
int mid=(l+r)>>1; down(now);
if(mid>=ll) modify(now*2,l,mid,ll,rr,z);
if(mid<rr) modify(now*2+1, mid+1,r,ll,rr,z);
update(now);
}
int ask(int now,int l,int r,int ll,int rr)
{
if(l>=ll && r<=rr) return d[now];
int mid=(l+r)>>1,ans=0;
down(now);
if(ll<=mid) ans+=ask(now*2,l,mid,ll,rr);
if(rr>mid) ans+=ask(now*2+1,mid+1,r,ll,rr);
if(ll<=mid && rr>mid && zr[now*2]==zl[now*2+1]) ans-=1;
return ans;
}
int main()
{
scanf("%d%d",&n,&ss);
for(i=1;i<=n;i++) scanf("%d",&c[i]);
built(1,1,2*n);
scanf("%d",&m);
x=n+1, y=n+n;
for(i=1;i<=m;i++)
{
scanf("%s",ch);
if(ch[0]=='R')
{
int k;
scanf("%d",&k);
if(b)x+=k, y+=k; else x-=k, y-=k;
if(y>2*n) y-=n, x-=n;
if(x<=0) x+=n, y+=n;
}
if(ch[0]=='F')
{
b^=1;
if(b) x+=1, y+=1;
else x-=1, y-=1;
if(x<=0) x+=n, y+=n;
if(y>2*n) y-=n, x-=n;
}
if(ch[0]=='S')
{
scanf("%d%d",&g,&h);
int op,oq;
if(b) op=y-g+1, oq=y-h+1;
else op=x+g-1, oq=x+h-1;
int t=find(1,1,2*n,op), k=find(1,1,2*n,oq);
gai(1,1,2*n,op,k); gai(1,1,2*n,oq,t);
if(op>n) op-=n; else op+=n;
if(oq>n) oq-=n; else oq+=n;
gai(1,1,2*n,op,k); gai(1,1,2*n,oq,t);
}
if(ch[0]=='P')
{
int k;
scanf("%d%d%d",&g,&h,&k);
int op,oq;
if(b) op=y-h+1, oq=y-g+1;
else op=x+g-1, oq=x+h-1;
if(oq<op)
{
modify(1,1,2*n,x,oq,k);
modify(1,1,2*n,op,y,k);
if(oq>n)
{
if(x<n) modify(1,1,2*n,x+n,n+n,k), modify(1,1,2*n,1,oq-n,k);
else modify(1,1,2*n,x-n,oq-n,k);
}
else modify(1,1,2*n,x+n,oq+n,k);
if(op<n)
{
if(y>n) modify(1,1,2*n,op+n,n+n,k),modify(1,1,2*n,1,y-n,k);
else modify(1,1,2*n,op+n,y+n,k);
}
else modify(1,1,2*n,op-n,y-n,k);
}
else
{
modify(1,1,2*n,op,oq,k);
if(op<n && oq>n) modify(1,1,2*n,op+n,2*n,k),modify(1,1,2*n,1,oq-n,k);
else if(op>n) modify(1,1,2*n,op-n,oq-n,k);
else modify(1,1,2*n,op+n,oq+n,k);
}
}
if(ch[0]=='C' && ch[1]=='S')
{
scanf("%d%d",&g,&h);
int op,oq;
if(b) op=y-h+1, oq=y-g+1;
else op=x+g-1, oq=x+h-1;
if(oq<op) oq+=n;
if(op>n) op-=n, oq-=n;
int k=ask(1,1,2*n,op,oq);
printf("%d
",k);
}
if(ch[0]=='C' && ch[1]!='S')
{
int k=ask(1,1,2*n,x,y);
if(k!=1 && find(1,1,2*n,x)==find(1,1,2*n,y)) k-=1;
printf("%d
",k);
}
}
}