1493: [NOI2007]项链工厂

Time Limit: 30 Sec  Memory Limit: 64 MB
Submit: 1256  Solved: 545
[Submit][Status][Discuss]

Description

Input


入文件第一行包含两个整数N, c,分别表示项链包含的珠子数目以及颜色 数目。第二行包含N 个整数,x1, x2…, xn,表示从位置1 到位置N
的珠子的颜色, 1 ≤ xi ≤ c。第三行包含一个整数Q,表示命令数目。接下来的Q 行每行一条命令, 如上文所述。

Output

对于每一个C 和CS 命令,应输出一个整数代表相应的答案。

Sample Input

5 3
1 2 3 2 1
4
C
R 2
P 5 5 2
CS 4 1

Sample Output

4
1

HINT

对于60%的数据,N ≤ 1 000,Q ≤ 1 000; 对于100%的数据,N ≤ 500 000,Q ≤ 500 000,c ≤ 1 000。

【思路】

线段树。

R F之后虽然珠子的顺序变了,但是相对顺序是不变的。

我们用MOV记录顺时针旋转量,F记录是否翻转。

如果翻转则MOV-=k,否则MOV+=k。然后用MOV计算出查询位置对应的原位置,在原位置上进行操作。

剩下的就是区间上的颜色修改以及统计颜色段数的问题了,可以用线段树完成。

注意珠子是环形的,别忘比较一下1和n的颜色。

【代码】

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; const int N = *1e5+;
int n,m,c,MOV,F,co[N];
//SEGMENT TREE
struct Trie{ int l,r,s,c,lc,rc,setv; }T[N*];
void pushdown(int u) {
if(T[u].l<T[u].r && T[u].setv!=-) {
int lc=u<<,rc=lc|;
T[lc].c=T[rc].c=T[lc].setv=T[rc].setv=T[u].setv;
T[lc].lc=T[lc].rc=T[rc].lc=T[rc].rc=T[u].setv;
T[lc].s=T[rc].s=;
T[u].setv=-;
}
}
void maintain(int u) {
int lc=u<<,rc=lc|;
T[u].s=T[lc].s+T[rc].s-(T[lc].rc==T[rc].lc);
T[u].lc=T[lc].lc,T[u].rc=T[rc].rc;
}
void build(int u,int L,int R) {
T[u].l=L,T[u].r=R; T[u].setv=-;
if(L==R) {
T[u].c=T[u].lc=T[u].rc=co[L]; T[u].s=;
return ;
}
int M=(L+R)>>;
build(u<<,L,M) , build(u<<|,M+,R);
maintain(u);
}
void update(int u,int L,int R,int x) {
pushdown(u);
if(L<=T[u].l && T[u].r<=R) {
T[u].setv=T[u].c=T[u].lc=T[u].rc=x;
T[u].s=;
}
else {
int M=(T[u].l+T[u].r)>>;
if(L<=M) update(u<<,L,R,x);
if(M<R) update(u<<|,L,R,x);
maintain(u);
}
}
int query(int u,int L,int R) {
pushdown(u);
if(L==T[u].l && T[u].r==R) {
return T[u].s;
}
else {
int M=(T[u].l+T[u].r)>>;
if(R<=M) return query(u<<,L,R);
else if(L>M) return query(u<<|,L,R);
else {
int ans=query(u<<,L,M);
ans+=query(u<<|,M+,R);
ans-=T[u<<].rc==T[u<<|].lc;
return ans;
}
}
}
int getcolor(int u,int x) {
pushdown(u);
if(T[u].l==T[u].r) return T[u].c;
else {
int M=(T[u].l+T[u].r)>>;
if(x<=M) return getcolor(u<<,x);
else return getcolor(u<<|,x);
}
} int get(int x) {
if(F) x=n+-x;
x-=MOV;
while(x<) x+=n;
while(x>n) x-=n;
return x;
}
void read(int& x) {
char c=getchar(); x=; int f=;
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)) x=x*+c-'',c=getchar();
}
int main() {
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
read(n),read(c);
int x,a,b,c; char s[];
for(int i=;i<=n;i++) read(co[i]);
build(,,n);
read(m);
while(m--) {
scanf("%s",s);
if(s[]=='R') {
read(a);
if(F) MOV-=a; else MOV+=a;
while(MOV<) MOV+=n;
while(MOV>n) MOV-=n;
} else
if(s[]=='F') F^=; else
if(s[]=='S') {
read(a),read(b);
a=get(a),b=get(b);
int c1=getcolor(,a),c2=getcolor(,b);
update(,a,a,c2),update(,b,b,c1);
} else
if(s[]=='P') {
read(a),read(b),read(c);
a=get(a),b=get(b);
if(F) swap(a,b);
if(a>b) update(,a,n,c),update(,,b,c);
else update(,a,b,c);
} else
if(s[] && strlen(s)==) {
int ans=query(,,n);
if(ans>&&T[].lc==T[].rc) ans--;
printf("%d\n",ans);
} else {
read(a),read(b);
a=get(a),b=get(b);
if(F) swap(a,b);
int ans;
if(a<=b) {
ans=query(,a,b);
if(a==&&b==n&&ans>&&T[].lc==T[].rc) ans--;
} else {
ans=query(,a,n)+query(,,b);
if(T[].lc==T[].rc) ans--;
}
printf("%d\n",ans);
}
}
return ;
}

bzoj 1493: [NOI2007]项链工厂(线段树)的更多相关文章

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

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

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

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

  3. 1493: [NOI2007]项链工厂

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

  4. BZOJ1493 [NOI2007]项链工厂

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

  5. BZOJ_1493_[NOI2007]项链工厂_Splay

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

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

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

  7. [BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并)

    [BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并) 题面 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1 ...

  8. [BZOJ 2653] middle(可持久化线段树+二分答案)

    [BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...

  9. bzoj 1537: [POI2005]Aut- The Bus 线段树

    bzoj 1537: [POI2005]Aut- The Bus 先把坐标离散化 设f[i][j]表示从(1,1)走到(i,j)的最优解 这样直接dp::: f[i][j] = max{f[i-1][ ...

随机推荐

  1. IniParse解析类

    说明 iniParse这个类是一个解析ini文件的类,他的功能和Windows下GetPrivateProfileString的功能一样,可以很方便的保存读取配置. 当然他不是只有GetPrivate ...

  2. OpenGl入门——视口及物体移动函数

    大学的时候有个选修课,要用OpenGl,很初级的内容,同样入门的学弟学妹适用 推荐个学习的资料NeHe的OpenGl教程,很完整而且有示例,讲的很明白.比某些破书好. 可以配合那本所谓的“红宝书”看看 ...

  3. [C#]『Task』任务并行库使用小计

    1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...

  4. CentOS 6.4 安装思维到图工具TheBrain

    最近学习中需要使用思维导图的工具,但是使用的系统是CentOS,在网上找到了一个比较好的思维导图工具:TheBrain,安装完成后还是汉化版的不错啊,由于用的是linux系统,还没有找到合适的截图软件 ...

  5. gulp和webpack初探

    gulp 真正“流程”化工具 我记得实习刚刚进公司看到grunt,还是有点蒙,之前一直是本地开发,游览器F5,没想到前端也需要“编译工具”.所以grunt一直给我的感觉是“编译工具”,你写的很多代码还 ...

  6. 读取Android APK文件签名的方法

    在微信开放平台等申请API key 和secret时经常要用到apk文件签名,那么如何读取呢? 下面贴一下相关读取源码: 一共两个文件MainActivity和MD5, package com.lcg ...

  7. 网络编程TCP/IP实现客户端与客户端聊天

    一.TCP/IP协议 既然是网络编程,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,另一个是如何进行可靠高效的数据传输.这里就要使用到TCP/IP协议. TCP/I ...

  8. 网站seo优化--jsoup 批量分析相关网站 标签,描述,关键词.

    网站seo优化--jsoup 批量分析相关网站 标签,描述,关键词. 因为自己写了一个磁力搜索网站Btgoogle,准备进行优化一下,需要分析其他的网站的优化情况. Java的Jsoup类库和PHP的 ...

  9. C语言中字符型和字符串型的区别?

    C语言中只有字符型类型,没有字符串型类型.字符类型用一个带符号的8位二进制编码表示,其性质与int相同,只是只有一个字节.表示字符的ASCII编码使用其中的0~127,所以要明白字符类型(char)其 ...

  10. armv7a-mediatek451_001_vfp-linux-gnueabi-gcc: directory: No such file or directory 编译error

    release/vm_linux/output/hisense_android/mt5399_cn_android_JB/rel/obj/oss/source/arm_mali_ko/mali400- ...