【BZOJ-1493】项链工厂 Splay
1493: [NOI2007]项链工厂
Time Limit: 30 Sec Memory Limit: 64 MB
Submit: 1440 Solved: 626
[Submit][Status][Discuss]
Description
.png)

Input
Output
对于每一个 C 和 CS 命令,应输出一个整数代表相应的答案。
Sample Input
1 2 3 2 1
4
C
R 2
P 5 5 2
CS 4 1
Sample Output
1
HINT

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的更多相关文章
- bzoj 1493: [NOI2007]项链工厂(线段树)
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1256 Solved: 545[Submit][Status] ...
- 数据结构(Splay平衡树): [NOI2007] 项链工厂
[NOI2007] 项链工厂 ★★★ 输入文件:necklace.in 输出文件:necklace.out 简单对比 时间限制:4 s 内存限制:512 MB [问题描述] T公司是一 ...
- BZOJ1493 [NOI2007]项链工厂
未完待续... 终于改对了 热泪盈眶.jpg 错误原因:pushdown的时候没有判断是否有左右儿子,也没当x=0 return,于是出现一些奇怪的错误 #include<bits/stdc++ ...
- bzoj1493[NOI2007]项链工厂 线段树
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1712 Solved: 723[Submit][Status] ...
- 【BZOJ1493】【NOI2007】项链工厂(线段树)
[BZOJ1493]项链工厂(线段树) 题面 BZOJ 洛谷 Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打 ...
- BZOJ_1493_[NOI2007]项链工厂_Splay
BZOJ_1493_[NOI2007]项链工厂_Splay Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算 ...
- 1493: [NOI2007]项链工厂
线段树. 真还就是个线段树.. 除去操作1,2的话,线段树很容易就处理了,问题在于如何处理操作1和2.(这点没想到).. 我们用一个delta维护操作1,如果没有旋转就+k,不然就-k. 每次读入i和 ...
- [题解]bzoj 1861 Book 书架 - Splay
1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1396 Solved: 803[Submit][Stat ...
- BZOJ1493 NOI2007 项链工厂 线段树模拟
提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493 题目大意:给一个数列,进行一系列操作.包括旋转,翻转,改变等操作,以及查询颜色段数. ...
随机推荐
- bzoj千题计划201:bzoj1820: [JSOI2010]Express Service 快递服务
http://www.lydsy.com/JudgeOnline/problem.php?id=1820 很容易想到dp[i][a][b][c] 到第i个收件地点,三个司机分别在a,b,c 收件地点的 ...
- 并查集:POJ 1182 食物链 复习
#include <iostream> #include <algorithm> #include <cstring> #include <cstdlib&g ...
- Javascript加速运动与减速运动
加速运动,即一个物体运动时速度越来越快:减速运动,即一个物体运动时速度越来越慢.现在用Javascript来模拟这两个效果,原理就是用setInterval或setTimeout动态改变一个元素与另外 ...
- CentOS 编译 GCC 7.2
CentOS 编译 GCC 7.2 下载源码 wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-7.2.0/gcc-7.2.0. ...
- iOS设置tableViewCell之间的间距(去掉UItableview headerview黏性)
经常在项目中遇到自定义cell的情况,而且要求cell之间有间距,但是系统没有提供改变cell间距的方法,怎么办? 方法1:自定义cell的时候加一个背景View,使其距离contentView的上下 ...
- Sortable.js
拖拽的时候主要由这几个事件完成, ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上 ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此 ...
- 【译】SQLskills SQL101:Trace Flags、ERRORLOG、Update Statistics
最近阅读SQLskills SQL101,将Erin Stellato部分稍作整理.仅提取自己感兴趣的知识点,详细内容请阅读原文. 一.Trace Flags推荐开启三个跟踪标记1118.3023.3 ...
- 转载 python多重继承C3算法
备注:O==object 2.python-C3算法解析: #C3 定义引用开始 C3 算法:MRO是一个有序列表L,在类被创建时就计算出来. L(Child(Base1,Base2)) = [ Ch ...
- 【Alsa】播放声音和录音详细流程
linux中,无论是oss还是alsa体系,录音和放音的数据流必须分析清楚.先分析alsa驱动层,然后关联到alsa库层和应用层. 二,链接分析: 1)链路一 usr/src/linux-source ...
- crontab挂定时任务
Linux shell基本知识 a)">" 与 ">>" 的作用是不一样的,前者使用本次输出内容替换原有文件的内容,后者则是把本次输出追加 ...