提交地址: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. Spring data mongodb 聚合,投射,内嵌数组文档分页.

    尽量别直接用 DBObject  ,Spring data mongodb 的api 本来就没什么多大用处,如果还直接用 DBObject 那么还需要自己去解析结果,说动做个对象映射,累不累 Spri ...

  2. 个人觉得实用的Python姿势

    以后会陆续补充 偶然在Python Cookbook看到一个format操作,想到一个问题, 感觉用了!r之后,会把传入的对象按照原来形式保留 d = {"foo": " ...

  3. flask项目开发中,遇到http 413错误

    在flask项目中,上传文件时后台报http 413 Request Entity Too Large 请求体太大错误! 解决的2种方法: 1.在flask配置中设置 MAX_CONTENT_LENG ...

  4. H3C路由交换常用命令

    1.查看Linux下查看端口状态 root@root:~# netstat -an|grep -E "6002|6003" 2.H3C交换机显示当前配置 [H3C]display ...

  5. Sublime codeIntel 配置支持php自动提示

    Sublime codeIntel 配置支持php自动提示 下载地址:https://github.com/SublimeCodeIntel/SublimeCodeIntel 安装方法:下载后放到su ...

  6. web开发性能优化---分布式篇

    1.分布式架构-独立站点开发 模块化结构化开发,实现多资源分站点,数据分库,为后期实现分布式部署做准备,主要分为以下几部分: web站点: 1.web前端站点 2.图片.文件资源站点 3.管理端站点4 ...

  7. ListView 无 DataSource 依然用 DataPager 翻页

    ListView 有 DataSource 使用 DataPager 翻页ListView 无 DataSource 使用 DataPager 翻页问题描述点击两次才能翻页返回上一页,内容为空解决方法 ...

  8. Latex基础__如何用latex编写矩阵、矩阵等式、方程组、等式左对齐

    数学矩阵和方程组是数学工作者经常遇到的,那么如何用latex书写处漂亮的方程组.矩阵.多个等式呢,下面将对这个问题一一做介绍.1. 写矩阵. 代码: \begin{equation} \left[ \ ...

  9. webpack3配置字体图标和打包相关问题

    webpak配置字体图标有两种方式 一.将字体图标和css打包到同一个文件中. 1.首先需要安装url-loader npm install --save-dev url-loader 2.相关配置如 ...

  10. C# Hook原理及EasyHook简易教程

    前言 在说C# Hook之前,我们先来说说什么是Hook技术.相信大家都接触过外挂,不管是修改游戏客户端的也好,盗取密码的也罢,它们都是如何实现的呢? 实际上,Windows平台是基于事件驱动机制的, ...