列表

详情


NC17516. [NOI2007]项链工厂

描述

T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。

该项链自助生产系统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能帮助T公司编写一个软件模拟系统吗?

一条项链包含N个珠子,每个珠子的颜色是1, 2, …, c中的一种。项链被固定在一个平板上,平板的某个位置被标记位置1,按顺时针方向其他位置被记为2,3,…,N。

你将要编写的软件系统应支持如下命令:

命令 参数限制 内容
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;
}

上一题