提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493

题目大意:给一个数列,进行一系列操作。包括旋转,翻转,改变等操作,以及查询颜色段数。

题目分析:数列中元素的相对位置没有改变,因此不需要用splay去做,而是可以用线段树解决这类问题。

旋转操作直接改变变量rotate,翻转操作用异或即可。每次询问先利用rotate求出当前1号位是谁,这样可以根据翻转标记确定区间。如果区间跨越n,那么合并的时候要考虑左边一段的右端和右边一段的左端。相同的时候答案要减少1.

对于swap操作,由于是单点的,可以暴力在树上做。

这题以我的代码水平来说比较难打。

代码如下:

 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; const int maxn = ;
struct node{
int lazy;
int lft,rgt,tot,full;
}t[maxn<<];
int n,c;
int x[maxn];
int fz,rt; // fanzhuan rotate
int tl,tr; void push_down(int now){
t[now<<].lazy = t[now<<|].lazy = t[now].lazy;
t[now].lft = t[now].rgt = t[now].lazy; t[now].tot = ;
t[now].lazy = ;t[now].full = ;
} void push_up(int now){
int L=(now<<),R = L+;
if(t[now].lazy)push_down(now);
if(t[L].lazy)push_down(L); if(t[R].lazy) push_down(R);
t[now].lft = t[L].lft; t[now].rgt = t[R].rgt;
t[now].tot = t[L].tot + t[R].tot;
if(t[L].rgt == t[R].lft) t[now].tot--;
if(t[L].full && t[R].full && t[L].rgt == t[R].rgt) t[now].full=;
else t[now].full = ;
} void build_tree(int l,int r,int now){
if(l == r){
t[now].lazy = ; t[now].lft = x[l]; t[now].rgt = x[l];
t[now].tot = ;t[now].full = ;
}else{
int mid = (l+r>>);int L=(now<<),R = L+;
build_tree(l,mid,L); build_tree(mid+,r,R);
push_up(now);
}
} void read(){
scanf("%d%d",&n,&c);
for(int i=;i<=n;i++){
scanf("%d",&x[i]);
}
build_tree(,n,);
} void Rotate(){
int now; scanf("%d",&now);
if(fz == ) rt += (n-now);
else rt += now;
rt %= n;
} int get_ans(int l,int r,int now){
if(now == ) tl = ,tr = n;
if(t[now].lazy) push_down(now);
if(tl > r || tr < l) return ;
if(tl >= l && tr <= r) return t[now].tot;
int mid = (tl+tr) / ;
int ans = ;
int tmp = tr; tr=mid;
int nnow = get_ans(l,r,now<<);
ans += nnow;
tr = tmp;tmp = tl; tl = mid+;
int know = get_ans(l,r,now<<|);
ans += know;
tl = tmp;
if(tr-tl!=&&t[now<<].rgt == t[now<<|].lft&&nnow&&know) ans--;
push_up(now);
return ans;
} int get_color(int ord,int now){
if(now == ) tl = ,tr = n;
if(t[now].lazy) {push_down(now);return t[now].lft;}
if(tl == tr) return t[now].lft;
int mid = (tl+tr)/;
int ans;
if(mid >= ord){tr = mid; ans = get_color(ord,now<<);}
else {tl = mid+; ans = get_color(ord,now<<|);}
push_up(now);
return ans;
} void Tpaint(int l,int r,int now,int xc){
if(now == ) tl = ,tr = n;
if(t[now].lazy) {push_down(now);}
if(tl > r || tr < l) return;
if(tl >= l && tr <= r) {t[now].lazy = xc;push_down(now);return;}
int mid = (tl+tr)/;
int tmp = tr;tr = mid;
Tpaint(l,r,now<<,xc);
tr = tmp; tmp = tl; tl = mid+;
Tpaint(l,r,now<<|,xc);
tl = tmp;
push_up(now);
} int cnt;
void Count(){
int l,r,flag=,flag2=;
char ch = getchar();
cnt++;
if(ch != 'S') {
l = ,r=n;
int ans = t[].tot-(t[].lft == t[].rgt && t[].full==);
printf("%d\n",ans);
return;
}else {
scanf("%d%d",&l,&r);
}
int st = (-rt); if(st <= ) st += n;
if(fz == ){
l = st-l+; r = st-r+;
if(l <= ) l += n; if(r <= ) r += n;
int ans = ;
if(l < r){
ans += get_ans(,l,);
ans += get_ans(r,n,);
if(t[].lft == t[].rgt) ans--;
}else ans += get_ans(r,l,);
printf("%d\n",ans);
}else{
l = st+l-; r = st+r-;
if(l > n) l -= n; if(r > n) r -= n;
int ans = ;
if(l > r){
ans += get_ans(,r,);
ans += get_ans(l,n,);
if(t[].lft == t[].rgt) ans--;
}else ans += get_ans(l,r,);
printf("%d\n",ans);
}
} void Paint(){
int l,r,xc; scanf("%d%d%d",&l,&r,&xc);
int st = (-rt); if(st <= ) st += n;
if(fz == ){
l = st-l+; r = st-r+;
if(l <= ) l += n; if(r <= ) r += n;
if(l < r){ Tpaint(,l,,xc); Tpaint(r,n,,xc);}
else Tpaint(r,l,,xc);
}else{
l = st+l-; r = st+r-;
if(l > n) l -= n; if(r > n) r -= n;
if(l > r){ Tpaint(,r,,xc); Tpaint(l,n,,xc);}
else Tpaint(l,r,,xc);
}
} void Swap(){
int l,r; scanf("%d%d",&l,&r);
int st = (-rt); if(st <= ) st += n;
if(fz == ){
l = st-l+; r = st-r+;
if(l <= ) l += n; if(r <= ) r+= n;
}else{
l = st+l-; r = st+r-;
if(l > n) l -= n; if(r > n) r -= n;
}
int nowl = get_color(l,),nowr = get_color(r,);
Tpaint(l,l,,nowr); Tpaint(r,r,,nowl);
} void work(){
int q; scanf("%d",&q);
for(int i=;i<=q;i++){
char ch = getchar();
while(ch > 'Z' || ch < 'A')ch = getchar();
switch(ch){
case 'R':{Rotate();break;}
case 'F':{fz ^= ;break;}
case 'S':{Swap();break;}
case 'P':{Paint();break;}
case 'C':{Count();break;}
}
}
} int main(){
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
read();
work();
return ;
}

BZOJ1493 NOI2007 项链工厂 线段树模拟的更多相关文章

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

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

  2. BZOJ1493 [NOI2007]项链工厂

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

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

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

  4. BZOJ_1493_[NOI2007]项链工厂_Splay

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

  5. 【BZOJ-1493】项链工厂 Splay

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

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

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

  7. hdu_5818_Joint Stacks(线段树模拟)

    题目链接:hdu_5818_Joint Stacks 题意: 给你两个栈,多了个合并操作,然后让你模拟 题解: 很容易想到O(1)的单个栈操作,O(n)的合并操作,这样肯定超时,所以我们要将时间复杂度 ...

  8. 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流

    昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...

  9. 2019牛客暑期多校训练营(第八场)E:Explorer(LCT裸题 也可用线段树模拟并查集维护连通性)

    题意:给定N,M,然后给出M组信息(u,v,l,r),表示u到v有[l,r]范围的通行证有效.问有多少种通行证可以使得1和N连通. 思路:和bzoj魔法森林有点像,LCT维护最小生成树.  开始和队友 ...

随机推荐

  1. Docker安装weblogic

    Docker容器安装weblogic详细教程 前提:已经安装后Docker,并且能正常使用 (1)获取镜像:  docker pull ismaleiva90/weblogic12 docker pu ...

  2. (转)Hanoi塔问题分析

    转自:http://shmilyaw-hotmail-com.iteye.com/blog/2077098 简介 关于Hanoi塔问题的分析,在网上的文章都写烂了.之所以打算写这篇文章,更多的是针对这 ...

  3. 标准库bind函数中使用占位符placeholders

    placeholders ,占位符.表示新的函数对象中参数的位置.当调用新的函数对象时,新函数对象会调用被调用函数,并且其参数会传递到被调用函数参数列表中持有与新函数对象中位置对应的占位符. 举个例子 ...

  4. python︱字符操作杂记(split、zip...)

    字符串特别是中文在python里面还是有很多需要注意的地方. . . . 一.字符串 . . 1.字符串连接 方式一:单个字符相连用 + 就可以: 方式二:list组内相连,可以用join: 方式三: ...

  5. 裁剪Ubuntu内核和模块管理2

    准备工作 通常要运行的第一个命令是: #cd /usr/src/linux;make mrproper 该命令确保源代码目录下没有不正确的.o文件以及文件的互相依赖.由于我们使用刚下载的完整的源程序包 ...

  6. vxWorks驱动架构

    Vxworks内核驱动基本结构: 三张表:1. 系统设备表  2. 系统驱动表 3. 文件描述符表     Vxworks 内部对每个设备使用DEV_HDR 数据结构进行表示: Typedef str ...

  7. Failed while installing Dynamic Web Module 3.0

    1.错误描述 2.错误原因 Java Web项目不满足Web Module 3.0,需要降低Web Module版本 3.解决办法 (1)降低Web Module版本为2.5 (2)修改jdk版本,升 ...

  8. Ubuntu 上 hi3531 交叉编译环境 arm-hisiv100nptl-linux 搭建过程

    安装SDK 1.Hi3531 SDK包位置     在"Hi3531_V100R001***/01.software/board"目录下,您可以看到一个 Hi3531_SDK_Vx ...

  9. java.util.zip.ZipException:ZIP file must have at least one entry

    1.错误描述 java.util.zip.ZipException:ZIP file must have at least one entry 2.错误原因 由于在导出文件时,要将导出的文件压缩到压缩 ...

  10. python datetime 与 time模块

    time模块 tmie.strptime :将时间字符串转化为时间类型 格式:time.strptime(string[string[, format]) 结果可以利用利用time.tm_year 返 ...