1493: [NOI2007]项链工厂
线段树。
真还就是个线段树。。
除去操作1,2的话,线段树很容易就处理了,问题在于如何处理操作1和2。(这点没想到)。。
我们用一个delta维护操作1,如果没有旋转就+k,不然就-k。
每次读入i和j的时候用trans处理一下,就成功在O(1)的时间解决了操作1和2。
细节很重要。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 2000000 + 10; struct Node {
int lc,rc,cnt;
}; struct segtree {
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1) int l[maxn],r[maxn],tag[maxn];
Node a[maxn];
int rev,delta,n,tmp; void trans(int &x,int &y) {
if(rev) { //反旋
x=(n-x+2-delta+n)%n;
y=(n-y+2-delta+n)%n;
swap(x,y);
}
else { //正旋
x=(x-delta+n)%n;
y=(y-delta+n)%n;
}
x=x?x:n;
y=y?y:n;
} void push(int x) {
if(!tag[x]) return;
a[lc(x)].lc=a[rc(x)].lc=tag[x];
a[lc(x)].rc=a[rc(x)].rc=tag[x];
tag[lc(x)]=tag[rc(x)]=tag[x];
a[lc(x)].cnt=a[rc(x)].cnt=1;
tag[x]=0;
} Node update(Node a,Node b) {
Node res;
res.lc=a.lc;
res.rc=b.rc;
res.cnt=a.cnt+b.cnt-(a.rc==b.lc);
return res;
} void update(int x) {
a[x]=update(a[lc(x)],a[rc(x)]);
} void build(int x,int L,int R) {
l[x]=L; r[x]=R;
if(L==R) {
scanf("%d",&tmp);
a[x].lc=a[x].rc=tmp;
a[x].cnt=1;
return;
}
int mid=(L+R)>>1;
build(lc(x),L,mid);
build(rc(x),mid+1,R);
update(x);
} void color(int x,int L,int R,int v) {
if(L>r[x] || R<l[x]) return;
if(L<=l[x] && r[x]<=R) {
tag[x]=v;
a[x].lc=a[x].rc=v;
a[x].cnt=1;
return;
}
push(x);
color(lc(x),L,R,v);
color(rc(x),L,R,v);
update(x);
} Node query(int x,int L,int R) {
if(L<=l[x] && r[x]<=R) return a[x];
int mid=(l[x]+r[x])>>1;
push(x);
if(R<=mid) return query(lc(x),L,R);
else if(L>mid) return query(rc(x),L,R);
else return update(query(lc(x),L,R),query(rc(x),L,R));
} void paws(int i,int j) {
trans(i,j);
Node cur;int ci,cj;
if(i<=j) {
cur=query(1,i,j);
ci=cur.lc; cj=cur.rc;
}
else {
cur=query(1,j,i);
cj=cur.lc; ci=cur.rc;
}
color(1,i,i,cj);
color(1,j,j,ci);
} void rotate() {
int k;
scanf("%d",&k);
if(rev) delta=(delta-k+n)%n; // 反旋
else delta=(delta+k)%n; // 正旋
} void paint(int i,int j,int v) {
trans(i,j);
if(i<=j) color(1,i,j,v);
else {
color(1,i,n,v);
color(1,1,j,v);
}
} void c1() {
Node cur;
cur=query(1,1,n);
printf("%d\n",max(cur.cnt-(cur.lc==cur.rc),1));
} void c2(int i,int j) {
trans(i,j);
Node cur;
if(i<=j) cur=query(1,i,j);
else cur=update(query(1,i,n),query(1,1,j));
printf("%d\n",cur.cnt);
} void init() {
int c;
scanf("%d%d",&n,&c);
rev=delta=0;
build(1,1,n);
}
}seg; char op[20];
int k,i,j,x,q; int main() {
seg.init();
scanf("%d",&q);
while(q--) {
scanf("%s",op);
if(op[0]=='R') seg.rotate();
else if(op[0]=='F') seg.rev^=1;
else if(op[0]=='S') {
scanf("%d%d",&i,&j);
seg.paws(i,j);
}
else if(op[0]=='P') {
scanf("%d%d%d",&i,&j,&x);
seg.paint(i,j,x);
}
else if(op[0]=='C' && op[1]=='S') {
scanf("%d%d",&i,&j);
seg.c2(i,j);
}
else seg.c1();
}
return 0;
}
1493: [NOI2007]项链工厂的更多相关文章
- bzoj 1493: [NOI2007]项链工厂(线段树)
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1256 Solved: 545[Submit][Status] ...
- BZOJ1493 [NOI2007]项链工厂
未完待续... 终于改对了 热泪盈眶.jpg 错误原因:pushdown的时候没有判断是否有左右儿子,也没当x=0 return,于是出现一些奇怪的错误 #include<bits/stdc++ ...
- bzoj1493[NOI2007]项链工厂 线段树
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1712 Solved: 723[Submit][Status] ...
- 数据结构(Splay平衡树): [NOI2007] 项链工厂
[NOI2007] 项链工厂 ★★★ 输入文件:necklace.in 输出文件:necklace.out 简单对比 时间限制:4 s 内存限制:512 MB [问题描述] T公司是一 ...
- BZOJ_1493_[NOI2007]项链工厂_Splay
BZOJ_1493_[NOI2007]项链工厂_Splay Description T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱. 最近T公司打算 ...
- BZOJ1493 NOI2007 项链工厂 线段树模拟
提交地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1493 题目大意:给一个数列,进行一系列操作.包括旋转,翻转,改变等操作,以及查询颜色段数. ...
- NOI2007项链工厂——sbTreap代码
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> ...
- NOI2007 项链工厂
题目链接:戳我 60pts 有一点容易写错的小细节: 比如说求全局的段数的时候,如果只有一种颜色,那么当左右端点相等时,就不要ans--了. 注意右端点小于左端点的情况. #include<io ...
- 【BZOJ-1493】项链工厂 Splay
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1440 Solved: 626[Submit][Status] ...
随机推荐
- 我只知道一点非常简单的关于MVC的验证
我只知道一些非常简单的关于MVC的验证 如题,我只知道一点非常简单的关于MVC的验证,所以如果您接触过MVC的验证,相信也就不用看了,这个且当作是学习笔记吧. 先小讲解一下他基本的五个从Model里打 ...
- 学习Linux第一天
1.简介: 记住这个名字:Linus Torvals 系统组成:Linux内核,Shell, 文件系统,实时程序 Tips:在系统启动过程中,使用Alt+F2组合键,可以查看Ubuntu启动的详细过程 ...
- win7下Chrome有两个图标的解决方法
摘抄自:http://www.sevenforums.com/browsers-mail/238406-windows-7-taskbar-creating-double-google-chrome- ...
- Html特殊字符转义处理
#region 将Html特殊字符转义处理 /// <summary> /// 将Html特殊字符转义处理 /// </summary> ...
- 浅谈Feature Scaling
浅谈Feature Scaling 定义:Feature scaling is a method used to standardize the range of independent variab ...
- 【C++基础】 指针&字符串&数组
先贴代码,总结以后再写,和5中内存分配方式密切相关 PS: str 返回整个字符串,str[0],*str返回首字符h char *strA(){ char str[]="hello!&qu ...
- recursion lead to out of memory
There are two storage areas involved: the stack and the heap. The stack is where the current state o ...
- UVA 291 The House Of Santa Claus (DFS求一笔画)
题意:从左下方1开始,一笔画出圣诞老人的屋子(不过话说,圣诞老人的屋子是这样的吗?这算是个屋子么),输出所有可以的路径. 思路:贴代码. #include <iostream> #incl ...
- javascript加速运动
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- lintcode :最长上升连续子序列
题目: 最长上升连续子序列 给定一个整数数组(下标从 0 到 n-1, n 表示整个数组的规模),请找出该数组中的最长上升连续子序列.(最长上升连续子序列可以定义为从右到左或从左到右的序列.) 样例 ...