NC17516. [NOI2007]项链工厂
描述
T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。
该项链自助生产系统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能帮助T公司编写一个软件模拟系统吗?
你将要编写的软件系统应支持如下命令:
命令 | 参数限制 | 内容 |
R k | 0<k><n>< td=""></n> </k> | 意为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命令,应输出一个整数代表相应的答案。
示例1
输入:
5 3 1 2 3 2 1 4 C R 2 P 5 5 2 CS 4 1
输出:
4 1
C++11(clang++ 3.9) 解法, 执行用时: 627ms, 内存消耗: 25764K, 提交时间: 2019-01-07 17:07:55
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<cmath> #define inf 0x7fffffff #define ll long long using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } bool rev; int n,m,delta; struct data{int l,r,sum;}; struct seg{int l,r,tag;data c;}t[2000005]; void cal(int &x,int &y) { if(rev) { x=(n+n+2-delta-x)%n; y=(n+n+2-delta-y)%n; swap(x,y); } else { x=(x-delta+n)%n; y=(y-delta+n)%n; } if(x==0)x=n;if(y==0)y=n; } data merge(data a,data b) { data tmp; tmp.l=a.l;tmp.r=b.r; tmp.sum=a.sum+b.sum; if(a.r==b.l)tmp.sum--; return tmp; } void update(int k) { t[k].c=merge(t[k<<1].c,t[k<<1|1].c); } void pushdown(int k) { if(!t[k].tag||t[k].l==t[k].r)return; int tag=t[k].tag;t[k].tag=0; t[k<<1].tag=t[k<<1|1].tag=tag; t[k<<1].c.l=t[k<<1|1].c.l=tag; t[k<<1].c.r=t[k<<1|1].c.r=tag; t[k<<1].c.sum=t[k<<1|1].c.sum=1; } void build(int k,int l,int r) { t[k].l=l;t[k].r=r; if(l==r) { t[k].c.l=t[k].c.r=read(); t[k].c.sum=1; return; } int mid=(l+r)>>1; build(k<<1,l,mid);build(k<<1|1,mid+1,r); update(k); } data query(int k,int x,int y) { pushdown(k); int l=t[k].l,r=t[k].r; if(l==x&&y==r)return t[k].c; int mid=(l+r)>>1; if(y<=mid)return query(k<<1,x,y); else if(x>mid)return query(k<<1|1,x,y); else { return merge(query(k<<1,x,mid),query(k<<1|1,mid+1,y)); } } void modify(int k,int x,int y,int val) { pushdown(k); int l=t[k].l,r=t[k].r; if(l==x&&y==r) { t[k].c.l=t[k].c.r=t[k].tag=val; t[k].c.sum=1; return; } int mid=(l+r)>>1; if(y<=mid)modify(k<<1,x,y,val); else if(x>mid)modify(k<<1|1,x,y,val); else { modify(k<<1,x,mid,val); modify(k<<1|1,mid+1,y,val); } update(k); } int main() { n=read();m=read(); build(1,1,n); char ch[5]; m=read(); int x,y,val; for(int i=1;i<=m;i++) { scanf("%s",ch); if(ch[0]=='R') { x=read(); if(rev)delta=(delta+n-x)%n; else delta=(delta+x)%n; } if(ch[0]=='F')rev^=1; if(ch[0]=='S') { x=read();y=read(); int a,b; cal(x,y);data ans; if(x>y) { ans=query(1,y,x); a=ans.r;b=ans.l; } else { ans=query(1,x,y); a=ans.l;b=ans.r; } modify(1,x,x,b);modify(1,y,y,a); } if(ch[0]=='P') { x=read();y=read();val=read(); cal(x,y); if(x<=y)modify(1,x,y,val); else { modify(1,x,n,val);modify(1,1,y,val); } } if(ch[0]=='C'&&ch[1]=='S') { x=read();y=read(); cal(x,y); data ans; if(x<=y)ans=query(1,x,y); else ans=merge(query(1,x,n),query(1,1,y)); printf("%d\n",ans.sum); } if(ch[0]=='C'&&ch[1]!='S') { data ans=query(1,1,n); int tmp=ans.sum; if(ans.l==ans.r) tmp=max(tmp-1,1); printf("%d\n",tmp); } } return 0; }