记录编号 60803 评测结果 AAAAAAAAAA
题目名称 [NOI 2007]项链工厂 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 2.163 s
提交时间 2013-05-30 14:07:26 内存使用 32.80 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<fstream>
#include<map>
#include<set>
#include<vector>
#include<cstring>
#include<queue>
#include<deque>
#include<algorithm>
#include<cmath>
using namespace std;
const int SIZEN=500999;
class SEG{
public:
	int l,r;
	int lchild,rchild;
	int sum;//不同颜色的区间数目
	int lcover,rcover;
	int carry;//0就是不同色,否则就是本段共同的颜色
	void build(int x,int y);
	void merge(void);
	void update(int c);
	void pushdown(void);
	int inqcolor(int x);
	void paint(int x,int y,int c);
	int getsum(int x,int y);
};
int color[SIZEN]={0};
SEG tree[SIZEN*2];
SEG& root=tree[0];
int tot;
#define lson tree[lchild]
#define rson tree[rchild]
void SEG::build(int x,int y){
	l=x,r=y;
	carry=0;
	if(x==y){
		lchild=rchild=-1;
		lcover=rcover=color[x];
		sum=1;
	}
	else{
		int mid=(x+y)>>1;
		lchild=++tot;
		lson.build(x,mid);
		rchild=++tot;
		rson.build(mid+1,y);
		merge();
	}
}
void SEG::merge(void){
	lcover=lson.lcover;
	rcover=rson.rcover;
	sum=lson.sum+rson.sum;
	if(lson.rcover==rson.lcover) sum--;
}
void SEG::update(int c){//染成上面传下来的的c
	sum=1;
	lcover=rcover=c;
	carry=c;
}
void SEG::pushdown(void){//单纯的下传标记
	if(!carry||l==r) return;
	lson.update(carry);
	rson.update(carry);
	carry=0;
}
int SEG::inqcolor(int x){//查询位置x的颜色
	if(r<x||l>x) return 0;//不包含
	if(l==r&&l==x)	return lcover;
	if(carry){
		pushdown();
		merge();
	}
	return lson.inqcolor(x)+rson.inqcolor(x);//两个之中一个是0另一个是值
}
void SEG::paint(int x,int y,int c){//[x,y]染成c
	if(r<x||l>y) return;
	if(l>=x&&r<=y){//包含
		sum=1;
		lcover=rcover=c;
		carry=c;
		pushdown();
		return;
	}
	pushdown();
	lson.paint(x,y,c);
	rson.paint(x,y,c);
	merge();
}
int SEG::getsum(int x,int y){//查询[x,y]中的段数
	if(r<x||l>y) return 0;
	if(l>=x&&r<=y) return sum;
	int mid=(l+r)>>1;
	pushdown();
	merge();
	int temp=lson.getsum(x,y)+rson.getsum(x,y);
	if(mid<x||mid>=y){
		return temp;
	}
	else{
		if(lson.rcover==rson.lcover) return temp-1;
		else return temp;
	}
}
int n,numc,q;
bool flipped;//是否被翻转
int tran;//顺时针移动位数
void offset(int &x){
	x-=tran;
	if(flipped)	x=n+2-x;
	while(x<=0) x+=n;
	while(x>n) x-=n;
}
void init(void){
	tot=0;
	tran=0,flipped=false;
	scanf("%d%d",&n,&numc);
	int i;
	for(i=1;i<=n;i++) scanf("%d",&color[i]);
	root.build(1,n);
}
int section(int x,int y){
	int temp;
	if(x<=y) temp=root.getsum(x,y);
	else temp=root.getsum(x,n)+root.getsum(1,y);
	if((x>y||(x==1&&y==n))&&temp>1&&root.lcover==root.rcover) temp--;
	return temp;
}
void swap(int &a,int &b){
	int temp=a;
	a=b;
	b=temp;
}
void MOD(int &x){
	while(x>n) x-=n;
	while(x<=0) x+=n;
}
int req;
void work(void){
	scanf("%d",&req);
	char str[5]={0};
	int i,temp,a,b;
	int c;
	int c1,c2;
	for(i=1;i<=req;i++){
		scanf("%s",str);
		if(str[0]=='R'){//旋转
			scanf("%d",&temp);
			tran+=temp;
			MOD(tran);
		}
		else if(str[0]=='F'){//翻转
			tran*=-1;
			flipped=!flipped;
			MOD(tran);
		}
		else if(str[0]=='S'){//调换
			scanf("%d%d",&a,&b);
			offset(a),offset(b);
			if(flipped) swap(a,b);
			c1=root.inqcolor(a),c2=root.inqcolor(b);
			root.paint(a,a,c2);
			root.paint(b,b,c1);
		}
		else if(str[0]=='P'){//染色
			scanf("%d%d%d",&a,&b,&c);
			offset(a),offset(b);
			if(flipped) swap(a,b);
			if(a<=b) root.paint(a,b,c);
			else{
				root.paint(a,n,c);
				root.paint(1,b,c);
			}
		}
		else if(str[0]=='C'&&str[1]=='S'){//查询区间
			scanf("%d%d",&a,&b);
			offset(a),offset(b);
			if(flipped) swap(a,b);
			printf("%d\n",section(a,b));
		}
		else if(str[0]=='C'){//查询全段
			printf("%d\n",section(1,n));
		}

	}
}
int main(){
	freopen("necklace.in","r",stdin);
	freopen("necklace.out","w",stdout);
	init();
	work();
	return 0;
}