P4130 [NOI2007] 项链工厂
P4130 [NOI2007] 项链工厂
题目背景
T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。
最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。该项链自助生产系
统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的
项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能
帮助T公司编写一个软件模拟系统吗?
题目描述
一条项链包含
被固定在一个平板上,平板的某个位置被标记位置
你将要编写的软件系统应支持如下命令:
输入格式
输入文件第一行包含两个整数
第二行包含
第三行包含一个整数
接下来的
【数据规模和约定】
对于100%的数据,
Solution:
假如没有那两个怪异的旋转和折叠操作,我们可以用线段树维护颜色段轻松 AC 本题。
我们思考一下旋转和折叠的本质:
不难发现,发生折叠之后珠子间的相对位置关系是没有改变的,我们只改变了编号,并且这种改变是可以快速计算出来的:一个点
然后我们思考带着旋转操作再维护新的节点编号:一个点被顺时针旋转了
所以我们只需要记录当前的项链是否折叠
Code:
#include<bits/stdc++.h> const int N=5e5+5; using namespace std; struct Tree{ int lc,rc,tag,ans; }; struct Segment_Tree{ Tree t[N<<2]; #define ls x<<1 #define rs x<<1|1 inline void paint(int x,int k) { t[x].lc=t[x].rc=t[x].tag=k;t[x].ans=1; } inline void pushdown(int x) { if(!t[x].tag)return; paint(ls,t[x].tag);paint(rs,t[x].tag); } inline Tree merge(Tree L,Tree R) { Tree T={L.lc ? L.lc : R.lc,R.rc ? R.rc : L.rc,0,0}; T.ans=L.ans+R.ans-(L.rc==R.lc); return T; } void upd(int x,int l,int r,int L,int R,int k) { if(L<=l&&r<=R){paint(x,k);return;} int mid=l+r>>1;pushdown(x); if(L<=mid)upd(ls,l,mid,L,R,k); if(mid<R)upd(rs,mid+1,r,L,R,k); t[x]=merge(t[ls],t[rs]); } void query(int x,int l,int r,int L,int R,Tree &T) { if(L<=l&&r<=R){T=merge(T,t[x]);return;} int mid=l+r>>1;pushdown(x); if(L<=mid)query(ls,l,mid,L,R,T); if(mid<R)query(rs,mid+1,r,L,R,T); } }T; int push,rev; int n,m,C; char c[10]; int id(int x) { if(rev)x=(push-x+2); else x=x-push; x=(x+n)%n; if(!x)x=n; return x; } void work() { cin>>n>>C; for(int i=1,x;i<=n;i++) { scanf("%d",&x);T.upd(1,1,n,i,i,x); } cin>>m; for(int i=1,l,r,x;i<=m;i++) { scanf("%s",c); if(c[0]=='R') { scanf("%d",&x); push+=x;push%=n; } if(c[0]=='F') { rev^=1;push=(n-push+n)%n; } if(c[0]=='S') { scanf("%d%d",&l,&r); l=id(l),r=id(r); Tree L={0},R={0}; T.query(1,1,n,l,l,L);T.query(1,1,n,r,r,R); T.upd(1,1,n,l,l,R.lc);T.upd(1,1,n,r,r,L.lc); } if(c[0]=='P') { scanf("%d%d%d",&l,&r,&x); l=id(l),r=id(r);if(rev)swap(l,r); if(l<=r){T.upd(1,1,n,l,r,x);} else{T.upd(1,1,n,l,n,x);T.upd(1,1,n,1,r,x);} } if(c[0]=='C'&&c[1]=='S') { scanf("%d%d",&l,&r); l=id(l),r=id(r);if(rev)swap(l,r); Tree ans={0}; if(l<=r)T.query(1,1,n,l,r,ans); else { Tree res={0}; T.query(1,1,n,l,n,ans);T.query(1,1,n,1,r,res); ans.ans=(ans.ans+res.ans-(ans.rc==res.lc)); } printf("%d\n",ans.ans); } if(c[0]=='C'&&c[1]!='S') { Tree ans=T.t[1]; ans.ans-=(ans.lc==ans.rc); ans.ans=max(ans.ans,1); printf("%d\n",ans.ans); } c[1]=' '; } } int main() { //freopen("P4130_2.in","r",stdin);freopen("P4130.out","w",stdout); work(); return 0; }