提交地址: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. python_crawler,批量下载文件

    这个第一个python3网络爬虫,参考书籍是<python网络数据采集>.该爬虫的主要功能是爬取某个网站,并将.rar,.doc,.docx,.zip文件批量下载. 后期将要改进的是,用后 ...

  2. Google 浏览器被劫持怎么办?

    chrome://version/ 输入以上语句,在命令行中可看到恶意网址,复制该命令行,修改后面的网址即可

  3. 如何使用 libqr 库生成二维码?

    使用 libqr 库只需 4 步即可生成二维码 1.初始化 QRCode 结构体 QRCode *qrInit(int version, int mode, int eclevel, int mask ...

  4. the c programing language 学习过程8

    glean 捡拾落穗; glean insight 深入了解 modeled模型化 peripheral外围的 himogeneous匀称的 intents 意图  excerpt摘录 intende ...

  5. hihoCoder1310 岛屿 (dfs)

    思路:首先dfs求得所有联通块,再搜索的同时把每个联通块的坐标都保存下来,然后把每个联通块处理一下–首先得到某个联通块的最小横坐标和纵坐标,然后让每个坐标去减去这个横坐标和纵坐标.相当于使得所有联通块 ...

  6. C. Vasya and String

    原题链接 C. Vasya and String High school student Vasya got a string of length n as a birthday present. T ...

  7. java读取数据写入txt文件并将读取txt文件写入另外一个表

    package com.xsw.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.F ...

  8. Java并发编程笔记1-竞争条件&初识原子类&可重入锁

    我们知道,在多线程访问一个共享变量的时候会发生安全问题. 首先看下面例子: public class Counter { private int count; public void add(){ t ...

  9. Visual Studio Code搭建python开发环境

    开发Python的环境有很多,原来已经在vs2013上面搭建好python的开发环境了,但是vs2013每次启动都占太多内存(太强大了吧),这下出了vs code,既轻量又酷炫,正好拿来试一试开发py ...

  10. PlateSpin备份服务器时SQL Server的一些活动信息

      以前写过一篇文章IO is frozen on database xxx, No user action is required", 主要是介绍PlateSpin在服务器层面做DR备份时 ...