BZOJ1493 NOI2007 项链工厂 线段树模拟
提交地址: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 项链工厂 线段树模拟的更多相关文章
- bzoj1493[NOI2007]项链工厂 线段树
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1712 Solved: 723[Submit][Status] ...
- BZOJ1493 [NOI2007]项链工厂
未完待续... 终于改对了 热泪盈眶.jpg 错误原因:pushdown的时候没有判断是否有左右儿子,也没当x=0 return,于是出现一些奇怪的错误 #include<bits/stdc++ ...
- bzoj 1493: [NOI2007]项链工厂(线段树)
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1256 Solved: 545[Submit][Status] ...
- BZOJ_1493_[NOI2007]项链工厂_Splay
BZOJ_1493_[NOI2007]项链工厂_Splay Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算 ...
- 【BZOJ-1493】项链工厂 Splay
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1440 Solved: 626[Submit][Status] ...
- 数据结构(Splay平衡树): [NOI2007] 项链工厂
[NOI2007] 项链工厂 ★★★ 输入文件:necklace.in 输出文件:necklace.out 简单对比 时间限制:4 s 内存限制:512 MB [问题描述] T公司是一 ...
- hdu_5818_Joint Stacks(线段树模拟)
题目链接:hdu_5818_Joint Stacks 题意: 给你两个栈,多了个合并操作,然后让你模拟 题解: 很容易想到O(1)的单个栈操作,O(n)的合并操作,这样肯定超时,所以我们要将时间复杂度 ...
- 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流
昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...
- 2019牛客暑期多校训练营(第八场)E:Explorer(LCT裸题 也可用线段树模拟并查集维护连通性)
题意:给定N,M,然后给出M组信息(u,v,l,r),表示u到v有[l,r]范围的通行证有效.问有多少种通行证可以使得1和N连通. 思路:和bzoj魔法森林有点像,LCT维护最小生成树. 开始和队友 ...
随机推荐
- ch11 持有对象
Java集合的基本类型:List.Set.Queue.Map 使用容器时若未指定泛型参数ArrayList apples=new ArrayList();,则容器中所有元素都为Object类型,使用时 ...
- Yii2框架RBAC(Role-Based Access Control)的使用
1.在项目的common/config/main.php文件的components中添加如下代码: 'authManager' => [ 'class' => 'yii\rbac ...
- 手把手教你在Ubuntu上分别安装Nginx、PHP和Mysql
手把手教你在Ubuntu上分别安装Nginx.PHP和Mysql
- 关于在windows10中的vmware9.0里面安装的ubuntukylin15.04和windows共享目录的一些反思
关于在windows10中的vmware9.0里面安装的ubuntukylin15.04和windows共享目录的一些反思 一.遇到的问题 如题目所说,在windows的虚拟机中和windo ...
- Qt 开发 MS VC 控件终极篇
Qt 开发 MS VC 控件终极篇 1. 使用 MSVC2015 通过项目向导创建 Qt ActiveQt Server 解决方案 项目配置:以下文件需要修改 1. 项目属性页->项目属性-&g ...
- hdu1006 Tick and Tick
原题链接 Tick and Tick 题意 计算时针.分针.秒针24小时之内三个指针之间相差大于等于n度一天内所占百分比. 思路 每隔12小时时针.分针.秒针全部指向0,那么只需要计算12小时内的百分 ...
- AutoAudit研究学习
AutoAudit介绍 AutoAudit这个是Paul Nielsen写的一个开源的审计跟踪的脚本项目,项目位于https://autoaudit.codeplex.com/上,Paul Nie ...
- Object Detection︱RCNN、faster-RCNN框架的浅读与延伸内容笔记
一.RCNN,fast-RCNN.faster-RCNN进化史 本节由CDA深度学习课堂,唐宇迪老师教课,非常感谢唐老师课程中的论文解读,很有帮助. . 1.Selective search 如何寻找 ...
- 【转载】使用SDL播放YUV图像数据(转)
SDL提供了针对YUV格式数据的直接写屏操作.废话不多说,直接上代码吧/** * file showyuv.c * author: rare * date: 2009/12/06 * email: d ...
- win7 vs2012+wdk8.0 搭建wdf驱动开发环境
开发环境搭建:系统:win7 x64工具:vs2012 + WDK8.0插件:wdfcoinstaller.msi(1)先安装vs2012,再安装wdk8.0,这样在打开vs2012时可以创建wind ...