#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib> using namespace std;
struct node
{
int data;
int left;
int right;
int key;
int size;
bool turn;
int ans;
int mark;
node* ls,*rs;
node(int dat=,int ke=)
{
data=dat;
key=ke;
left=data;
right=data;
size=;
turn=false;
mark=;
ans=;
ls=NULL;
rs=NULL;
}
}no[]; void pushdown(node* now)
{
if (now->mark)
{
if (now->ls)
{
now->ls->data=now->mark;
now->ls->mark=now->mark;
now->ls->left=now->mark;
now->ls->right=now->mark;
now->ls->ans=;
}
if (now->rs)
{
now->rs->data=now->mark;
now->rs->mark=now->mark;
now->rs->left=now->mark;
now->rs->right=now->mark;
now->rs->ans=;
}
now->mark=;
}
if (now->turn)
{
node* l=now->ls;
node* r=now->rs;
if (now->ls)
now->ls->left^=now->ls->right^=now->ls->left^=now->ls->right;
if (now->rs)
now->rs->left^=now->rs->right^=now->rs->left^=now->rs->right;
now->ls=r;
now->rs=l;
if (now->ls) now->ls->turn=!now->ls->turn;
if (now->rs) now->rs->turn=!now->rs->turn;
now->turn=false;
}
} void update(node* now)
{
now->size=;
now->ans=;
now->left=now->data;
now->right=now->data;
if (now->ls)
{
now->size+=now->ls->size;
now->ans+=now->ls->ans;
now->left=now->ls->left;
}
if (now->rs)
{
now->size+=now->rs->size;
now->ans+=now->rs->ans;
now->right=now->rs->right;
}
if (now->ls)
if (now->ls->right==now->data) now->ans--;
if (now->rs)
if (now->rs->left==now->data) now->ans--;
} node* merge(node* a,node* b)
{
if (!b) return a;
if (!a) return b;
pushdown(a);
pushdown(b);
if (a->key<=b->key)
{
a->rs=merge(a->rs,b);
update(a);
return a;
}
else
{
b->ls=merge(a,b->ls);
update(b);
return b;
}
} struct npair
{
node* l,*r;
npair(node* a,node* b)
{
l=a;
r=b;
}
}; npair split(node* a,int k)
{
if (!a) return npair(NULL,NULL);
if (k==) return npair(NULL,a);
pushdown(a);
if (a->ls)
{
if (a->ls->size>=k)
{
npair km=split(a->ls,k);
a->ls=km.r;
update(a);
return npair(km.l,a);
}
else
{
npair km=split(a->rs,k-a->ls->size-);
a->rs=km.l;
update(a);
return npair(a,km.r);
}
}
else
{
npair km=split(a->rs,k-);
a->rs=km.l;
update(a);
return npair(a,km.r);
}
}
node* insert(node* root,node* newnode)
{
return merge(root,newnode);
} void turn(node* now)
{
now->turn=!now->turn;
now->left^=now->right^=now->left^=now->right;
} node* rotate(node* root,int num)
{
int n=root->size;
num=num%n;
int k=n-num;
npair km = split(root,k);
return merge(km.r,km.l);
} node* flip(node* root)
{
int n=root->size;
int r;
if (n%==)
{
r=n/+;
}
else
{
r=n/;
}
npair km=split(root,r);
npair km2=split(km.l,);
if (n%==)
{
turn(km2.r);
turn(km.r);
return merge(merge(km2.l,km.r),km2.r);
}
else
{
npair km3=split(km.r,);
turn(km2.r);
turn(km3.r);
return merge(merge(km2.l,km3.r),merge(km3.l,km2.r));
}
} node* swap(node* root,int i,int j)
{
if (i>j) i^=j^=i^=j;
if (i==j) return root;
npair km=split(root,i);
npair km2=split(km.l,i-);
npair km3=split(km.r,j-i);
npair km4=split(km3.l,j-i-);
return merge(merge(merge(km2.l,km4.r),km4.l),merge(km2.r,km3.r));
} node* paint(node* root,int i,int j,int x)
{
int n=root->size;
if (i<=j)
{
npair km=split(root,i-);
npair km2=split(km.r,j-i+);
km2.l->mark=x;
km2.l->data=x;
km2.l->ans=;
km2.l->left=x;
km2.l->right=x;
return merge(km.l,merge(km2.l,km2.r));
}
else
{
npair km=split(root,j);
int nn=km.r->size;
npair km2=split(km.r,nn-n+i-);
km.l->mark=x;
km.l->data=x;
km.l->ans=;
km.l->left=x;
km.l->right=x;
km2.r->mark=x;
km2.r->data=x;
km2.r->ans=;
km2.r->left=x;
km2.r->right=x;
return merge(km.l,merge(km2.l,km2.r));
}
} node* root;
int countS(int i,int j)
{
int n=root->size;
if (i<=j)
{
npair km=split(root,i-);
npair km2=split(km.r,j-i+);
int ret=km2.l->ans;
root=merge(km.l,merge(km2.l,km2.r));
return ret;
}
else
{
npair km=split(root,j);
int nn=km.r->size;
npair km2=split(km.r,nn-n+i-);
int ret=km.l->ans+km2.r->ans;
if (km.l->left==km2.r->right) ret--;
root=merge(km.l,merge(km2.l,km2.r));
return ret;
}
} int count()
{
int ret=root->ans;
if (root->left==root->right&&ret!=) ret--;
return ret;
} void print(node* now,bool b)
{
if (!now) return;
b=b^now->turn;
// if (!b)
print(now->ls,b);
// else
// print(now->rs,b);
printf("data: %d size: %d mark: %d turn: %d ans: %d left: %d right: %d\n",now->data,now->size,now->mark,now->turn,now->ans,now->left,now->right);
// if (!b)
print(now->rs,b);
// else
// print(now->ls,b);
} void print(node* now)
{
if (!now) return;
pushdown(now);
print(now->ls);
printf("%d\n",now->data);
print(now->rs);
} int cnt=-;
int main()
{
int n,c;
scanf("%d%d",&n,&c);
int j;
for (int i=;i<=n;++i)
{
scanf("%d",&j);
node* q=&no[++cnt];
*q=node(j,rand());
root=insert(root,q);
}
int m;
scanf("%d",&m);
char cmd[];
int l,r,k;
for (int i=;i<=m;++i)
{
scanf("%s",cmd);
if (cmd[]=='R'){scanf("%d",&k);root=rotate(root,k);}
if (cmd[]=='F'){root=flip(root);}
if (cmd[]=='S'){scanf("%d%d",&l,&r);root=swap(root,l,r);}
if (cmd[]=='P'){scanf("%d%d%d",&l,&r,&k);root=paint(root,l,r,k);}
if (cmd[]=='C'&&cmd[]!='S'){printf("%d\n",count());}
if (cmd[]=='C'&&cmd[]=='S'){scanf("%d%d",&l,&r);printf("%d\n",countS(l,r));}
// printf("%d\n",i);
// printf("--------------------\n");
// print(root,false);
// printf("--------------------\n");
}
return ;
}

NOI2007项链工厂——sbTreap代码的更多相关文章

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

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

  2. BZOJ_1493_[NOI2007]项链工厂_Splay

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

  3. BZOJ1493 [NOI2007]项链工厂

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

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

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

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

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

  6. BZOJ1493 NOI2007 项链工厂 线段树模拟

    提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493 题目大意:给一个数列,进行一系列操作.包括旋转,翻转,改变等操作,以及查询颜色段数. ...

  7. 1493: [NOI2007]项链工厂

    线段树. 真还就是个线段树.. 除去操作1,2的话,线段树很容易就处理了,问题在于如何处理操作1和2.(这点没想到).. 我们用一个delta维护操作1,如果没有旋转就+k,不然就-k. 每次读入i和 ...

  8. NOI2007 项链工厂

    题目链接:戳我 60pts 有一点容易写错的小细节: 比如说求全局的段数的时候,如果只有一种颜色,那么当左右端点相等时,就不要ans--了. 注意右端点小于左端点的情况. #include<io ...

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

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

随机推荐

  1. iptables详解(5):iptables匹配条件总结之二(常用扩展模块)

    所属分类:IPtables  Linux基础 在本博客中,从理论到实践,系统的介绍了iptables,如果你想要从头开始了解iptables,可以查看iptables文章列表,直达链接如下 iptab ...

  2. 【原创】使用JS封装的一个小型游戏引擎及源码分享

    1 /** * @description: 引擎的设计与实现 * @user: xiugang * @time: 2018/10/01 */ /* * V1.0: 引擎实现的基本模块思路 * 1.创建 ...

  3. AtCoder ABC 085C/D

    C - Otoshidama 传送门:https://abc085.contest.atcoder.jp/tasks/abc085_c 有面值为10000.5000.1000(YEN)的纸币.试用N张 ...

  4. 3 Java的基本程序设计结构

        本章主要内容: 一个简单的Java应用程序 注释 数据类型 变量 运算符 字符串 输入输出 控制流 大数值 数组       本章主要介绍程序设计的基本概念(如数据类型.分支以及循环)在Jav ...

  5. C#关键字详解第三节

    byte:字节 字节是计算机信息技术用于计量存储容量的一种计量单位,通常情况下一字节等于八位,也在一些计算机编程 语言中表示数据类型和语言字符.这是百度百科给出的解释,在C#语言中byte也可以是一种 ...

  6. Tkinter图形界面设计(GUI)

    [因为这是我第一个接触的GUI图形界面python库,现在也不用了,所以大多数内容都来自之前花 钱买的一些快速入门的内容,可以当作简单的知识点查询使用] 在此声明:内容来自微信公众号GitChat,付 ...

  7. spring配置Converter、Formatter日期转换器

    最近有点恶补spring的嫌疑,然后学了一点知识点纪录在此. 往往在项目中我们会遇到前端页面输入一个日期类型的字符串传递到后端后我们需要去做转换.甚至在传递的过程中就会报错. Spring有一个一劳永 ...

  8. Hibernate注解开发教程

    目录 第一章 类级别注解 1-1 本章简介 一.Hibernate注解简介 二.JPA与Hibernate的关系 三.Hibernate注解的分类 1-2 准备工作 1-3 @Entity注解 1-4 ...

  9. fixed_date , 赋权技巧 ,procedure执行方式, PL/SQL注意的地方

    本文讨论4个知识点, 1. fixed_date参数 2. 赋权技巧 3. procedure执行的方式 4. PL/SQL中要注意的几个地方 fixed_date参数 客户想修改oracle的 系统 ...

  10. HDU 4503

    可以反过来求不是相同关系的小朋友.相当于染色问题吧. 对于A小朋友,它的T个朋友和另外的(N-1-T)个同学就可以组成一个这样的三角形.T*(N-1-T),由于一条非染色边被计算两次,所以除以2. # ...