1493: [NOI2007]项链工厂

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 1440  Solved: 626
[Submit][Status][Discuss]

Description

T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。
最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。该项链自助生产系统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能帮助T公司编写一个软件模拟系统吗?一条项链包含 N 个珠子,每个珠子的颜色是 1,2,…,c 中的一种。项链被固定在一个平板上,平板的某个位置被标记位置 1 ,按顺时针方向其他位置被记为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

HINT

注意旋转命令旋转“珠子”但不改变“位置”的编号,而反转命令始终以位置 1 为对称轴。例如当 N=10 时,项
链上的位置编号如图1:

但注意此时项链上的位置编号仍然如图1所示,于是翻转的对称轴不变。因而再执行一次“F”命令时,项链的颜色如图4所示。
2. 关于CountSegment命令CS命令表示查询一个“线段”中有多少个“部分”。尤其注意当查询的长度等于 N 时,我们仍然将查询部分作为“线段”理解。例如在图4所示的情况中,执行“CS 1 10”命令,查询从位置 1 开始到位置 10 结束的这个长度为 10 的线段中有多少个“部分”,于是得到返回值 3 。与之形成对照的是,若执行“C”命令,返回值则为 2

Source

Solution

所有操作Splay都可以做,那就直接搞了。

维护只需要维护 颜色段数、左端颜色、右端颜色 即可。

R操作就是把最后$k$个切掉连到前面,F操作就是区间$[2,N]$翻转,其余的打打标记很基础了,先旋转操作处理完再转回来就好。

C查询就是先CS查询$[1,N]$再判断断点衔接就好了..注意纯色段不能直接$-1$

Splay的常数好像有点大,调试的时候突然想到可以利用线段树来做..代码量和常数应该会小不少....

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN 500010
int N,C,Q,a[MAXN]; namespace SplayTree{
#define lson(x) son[x][0]
#define rson(x) son[x][1]
int size[MAXN],fa[MAXN],son[MAXN][2],sz,root;
int val[MAXN],lc[MAXN],rc[MAXN],cnt[MAXN],rev[MAXN],cov[MAXN];
inline void Newnode(int &x,int last,int v)
{
x=++sz;
fa[x]=last; son[x][0]=son[x][1]=0;
val[x]=lc[x]=rc[x]=v;
cnt[x]=v? 1:0;
}
inline void Update(int x)
{
if (!x) return;
size[x]=size[lson(x)]+size[rson(x)]+1;
cnt[x]=cnt[lson(x)]+cnt[rson(x)]+1;
lc[x]=rc[x]=val[x];
if (lson(x)) lc[x]=lc[lson(x)],cnt[x]-=(val[x]==rc[lson(x)]? 1:0);
if (rson(x)) rc[x]=rc[rson(x)],cnt[x]-=(val[x]==lc[rson(x)]? 1:0);
}
inline int Build(int l,int r,int last)
{
int mid=(l+r)>>1,x;
Newnode(x,last,a[mid]);
if (mid-1>=l) son[x][0]=Build(l,mid-1,x);
if (mid+1<=r) son[x][1]=Build(mid+1,r,x);
Update(x);
return x;
}
inline void Rev(int x) {if (!x) return; rev[x]^=1; swap(son[x][1],son[x][0]); swap(lc[x],rc[x]);}
inline void Cov(int x,int c) {if (!x) return; cov[x]=c; rev[x]=0; cnt[x]=1; lc[x]=rc[x]=val[x]=c;}
inline void Pushdown(int x)
{
if (cov[x])
Cov(son[x][0],cov[x]),Cov(son[x][1],cov[x]),cov[x]=0;
if (rev[x])
Rev(son[x][0]),Rev(son[x][1]),rev[x]^=1;
}
inline int Right(int x) {return son[fa[x]][1]==x;}
inline void Rotate(int x)
{
int y=fa[x],z=fa[y],w=Right(x);
Pushdown(y); Pushdown(x);
son[y][w]=son[x][w^1]; fa[son[y][w]]=y;
fa[y]=x; son[x][w^1]=y; fa[x]=z;
if (z) son[z][son[z][1]==y]=x;
Update(y); Update(x);
}
inline void Splay(int x,int tar)
{
for (int y; (y=fa[x])!=tar; Rotate(x))
if (fa[y]!=tar) Rotate(Right(x)==Right(y) ? y:x);
if (!tar) root=x;
}
inline int Find(int x,int k)
{
Pushdown(x);
if (size[son[x][0]]>=k) return Find(son[x][0],k);
if (size[son[x][0]]+1==k) return x;
return Find(son[x][1],k-size[son[x][0]]-1);
}
inline int Split(int l,int r)
{
int x=Find(root,l),y=Find(root,r+2);
Splay(x,0); Splay(y,root); return lson(rson(root));
}
inline void Move(int k)
{
if (!k || k==N) return;
int x=Split(N-k+1,N),y=fa[x];
fa[x]=0; son[y][0]=0;
Update(y); Update(fa[y]);
int xx=Find(root,1),yy=Find(root,2);
Splay(xx,0); Splay(yy,root);
son[rson(root)][0]=x; fa[x]=rson(root);
Update(rson(root)); Update(root);
}
inline void Cover(int l,int r,int c)
{
int x;
if (l<=r)
x=Split(l,r),Cov(x,c);
else
Move(N-l+1),Cover(1,r+N-l+1,c),Move(l-1);
}
inline int Query(int l,int r)
{
int x;
if (l<=r)
return cnt[Split(l,r)];
else
return Move(N-l+1),x=Query(1,r+N-l+1),Move(l-1),x;
}
inline int Query()
{
int x=cnt[Split(1,N)],lc=val[Find(root,2)],rc=val[Find(root,N+1)];
return rc==lc? max(x-1,1):x;
}
inline void Swap(int x,int y)
{
int xc=val[Find(root,x+1)],yc=val[Find(root,y+1)];
Cover(x,x,yc); Cover(y,y,xc);
}
inline void Rever() {int x=Split(2,N); Rev(x);}
}using namespace SplayTree; int main()
{
N=read(),C=read();
for (int i=1; i<=N; i++) a[i]=read(); Newnode(root,0,0);
Newnode(son[root][1],root,0);
son[son[root][1]][0]=SplayTree::Build(1,N,son[root][1]); Q=read();
while (Q--) {
char opt[3]; scanf("%s",opt+1);
int x,y,c,k;
switch (opt[1]) {
case 'R' : k=read(); SplayTree::Move(k); break;
case 'F' : SplayTree::Rever(); break;
case 'S' : x=read(),y=read(); SplayTree::Swap(x,y); break;
case 'P' : x=read(),y=read(),c=read(); SplayTree::Cover(x,y,c); break;
case 'C' : if (opt[2]=='S') x=read(),y=read(),printf("%d\n",SplayTree::Query(x,y)); else printf("%d\n",SplayTree::Query()); break;
}
}
return 0;
}

  

【BZOJ-1493】项链工厂 Splay的更多相关文章

  1. bzoj 1493: [NOI2007]项链工厂(线段树)

    1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1256  Solved: 545[Submit][Status] ...

  2. 数据结构(Splay平衡树): [NOI2007] 项链工厂

    [NOI2007] 项链工厂 ★★★   输入文件:necklace.in   输出文件:necklace.out   简单对比 时间限制:4 s   内存限制:512 MB [问题描述] T公司是一 ...

  3. BZOJ1493 [NOI2007]项链工厂

    未完待续... 终于改对了 热泪盈眶.jpg 错误原因:pushdown的时候没有判断是否有左右儿子,也没当x=0 return,于是出现一些奇怪的错误 #include<bits/stdc++ ...

  4. bzoj1493[NOI2007]项链工厂 线段树

    1493: [NOI2007]项链工厂 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 1712  Solved: 723[Submit][Status] ...

  5. 【BZOJ1493】【NOI2007】项链工厂(线段树)

    [BZOJ1493]项链工厂(线段树) 题面 BZOJ 洛谷 Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打 ...

  6. BZOJ_1493_[NOI2007]项链工厂_Splay

    BZOJ_1493_[NOI2007]项链工厂_Splay Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算 ...

  7. 1493: [NOI2007]项链工厂

    线段树. 真还就是个线段树.. 除去操作1,2的话,线段树很容易就处理了,问题在于如何处理操作1和2.(这点没想到).. 我们用一个delta维护操作1,如果没有旋转就+k,不然就-k. 每次读入i和 ...

  8. [题解]bzoj 1861 Book 书架 - Splay

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1396  Solved: 803[Submit][Stat ...

  9. BZOJ1493 NOI2007 项链工厂 线段树模拟

    提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493 题目大意:给一个数列,进行一系列操作.包括旋转,翻转,改变等操作,以及查询颜色段数. ...

随机推荐

  1. TCP和IP的三次握手和第四次挥手

    TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确 ...

  2. SQL语句(十一)函数查询

    (十一)函数查询 1. 聚合函数 对一组值进行计算,得到一个返回值 SUM(), 求和 AVG(), 求平均 MIN(), 求最小 MAX(), 求最大 COUNT(), 计数,即个数 --例1 求所 ...

  3. python学习笔记7-excel操作

    一.操作excel import xlwt book = xlwt.Workbook() #新建一个excel sheet = book.add_sheet('sheet1') #添加一个sheet页 ...

  4. mysql统计一个字段的多种状态

    假如我有下面的表:ID    Item           status            updatetime    author1    a        1        2014-01-0 ...

  5. sync 解释

    sync命令用于强制被改变的内容立刻写入磁盘,更新超块信息. 在Linux/Unix系统中,在文件或数据处理过程中一般先放到内存缓冲区中,等到适当的时候再写入磁盘,以提高系统的运行效率.sync命令则 ...

  6. OPENCV SVM介绍和自带例子

    依据机器学习算法如何学习数据可分为3类:有监督学习:从有标签的数据学习,得到模型参数,对测试数据正确分类:无监督学习:没有标签,计算机自己寻找输入数据可能的模型:强化学习(reinforcement ...

  7. ***PHP 遍历数组的方法foreach

    foreach  http://php.net/manual/zh/control-structures.foreach.php (PHP 4, PHP 5) foreach 语法结构提供了遍历数组的 ...

  8. IntelIJ IDEA配置Tomcat遇到问题Error during artifact deployment. See server log for details

    IntelIJ IDEA在配置tomcat的时候会遇到Error during artifact deployment. See server log for details.这样的问题,我的系统是W ...

  9. mavean项目的jar位置的影响

    由于项目的数据库需求改变了,有mysql数据库变为oracle的,那么对于项目就是需要改变数据库连接池.这个项目运用了mavean框架,那么下载jar在pom.xml文件中填写就可以了,但是oracl ...

  10. CSS3中border-image属性详解

    border-images可以说也是CSS3中的重量级属性,如同圆角.边框颜色属性border-color.块阴影属性一样,也是属于边框属性中的一员. 从其字面意思上看,我们可以理解为“边框-图片”, ...