1493: [NOI2007]项链工厂

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);
		}
		
	}
}
原文地址:https://www.cnblogs.com/ZUTTER/p/9888367.html