BZOJ_2120_数颜色_Set+树状数组+主席树
BZOJ_2120_数颜色_Set+树状数组+主席树
Description
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令: 1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。为了满足墨墨的要求,你知道你需要干什么了吗?
Input
第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。
Output
对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。
Sample Input
1 2 3 4 5 5
Q 1 4
Q 2 6
R 1 2
Q 1 4
Q 2 6
Sample Output
4
3
4
HINT
对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
记录一下第i位置左边第一个和i位置颜色相等的位置L[i]。
然后查询区间[x,y]就相当于查询区间中有多少L[]小于x。
可以用主席树来维护。
修改的话修改原颜色的后继和新颜色的后继和它本身即可,这个可以对所有颜色开一个set来实现。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
#define ms multiset<int>
#define N 10050
ms S[1000050];
int L[N],a[N],n,m,now[1000050];
int t[N*800],ls[N*800],rs[N*800],cnt,root[N];
int lx,ly,ax[N],ay[N];
char opt[10];
void update(int l,int r,int x,int v,int &p) {
if(!p) p=++cnt;
t[p]+=v;
if(l==r) return ;
int mid=(l+r)>>1;
if(x<=mid) update(l,mid,x,v,ls[p]);
else update(mid+1,r,x,v,rs[p]);
}
int query(int l,int r,int x) {
int i;
if(l==r) {
int re=0;
for(i=1;i<=lx;i++) re+=t[ax[i]];
for(i=1;i<=ly;i++) re-=t[ay[i]];
return re;
}
int mid=(l+r)>>1;
int sizls=0;
for(i=1;i<=lx;i++) sizls+=t[ls[ax[i]]];
for(i=1;i<=ly;i++) sizls-=t[ls[ay[i]]];
if(x<=mid) {
for(i=1;i<=lx;i++) ax[i]=ls[ax[i]];
for(i=1;i<=ly;i++) ay[i]=ls[ay[i]];
return query(l,mid,x);
}else {
for(i=1;i<=lx;i++) ax[i]=rs[ax[i]];
for(i=1;i<=ly;i++) ay[i]=rs[ay[i]];
return query(mid+1,r,x)+sizls;
}
}
void fix(int p,int v) {
int i;
for(i=p;i<=n;i+=i&(-i)) update(0,n,L[p],-1,root[i]);
L[p]=v;
for(i=p;i<=n;i+=i&(-i)) update(0,n,L[p],1,root[i]);
}
int main() {
scanf("%d%d",&n,&m);
int i,j,x,y;
for(i=1;i<=n;i++) {
scanf("%d",&a[i]);
S[a[i]].insert(i);
L[i]=now[a[i]];
now[a[i]]=i;
for(j=i;j<=n;j+=j&(-j)) {
update(0,n,L[i],1,root[j]);
}
}
while(m--) {
scanf("%s%d%d",opt,&x,&y);
if(opt[0]=='Q') {
lx=ly=0;
for(i=y;i;i-=i&(-i)) ax[++lx]=root[i];
for(i=x-1;i;i-=i&(-i)) ay[++ly]=root[i];
printf("%d\n",query(0,n,x-1));
}else {
int pre=0,nxt=0;
ms::iterator it; it=S[a[x]].lower_bound(x);
if(it!=S[a[x]].begin()) pre=*(--it),++it;
it++;
if(it!=S[a[x]].end()) nxt=*it;
if(nxt) fix(nxt,pre); S[a[x]].erase(x);
S[y].insert(x);
a[x]=y; int newpre=0,newnxt=0;
it=S[y].lower_bound(x);
if(it!=S[y].begin()) newpre=*(--it),++it;
it++;
if(it!=S[y].end()) newnxt=*it;
fix(x,newpre);
if(newnxt) fix(newnxt,x);
// printf("%d %d %d %d\n",pre,nxt,newpre,newnxt); }
}
}
BZOJ_2120_数颜色_Set+树状数组+主席树的更多相关文章
- zoj2112 树状数组+主席树 区间动第k大
Dynamic Rankings Time Limit: 10000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Subm ...
- BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树
BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...
- P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]
题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...
- 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- [luoguP1972] [SDOI2009]HH的项链(莫队 || 树状数组 || 主席树)
传送门 莫队基础题,适合我这种初学者. 莫队是离线算法,通常不带修改,时间复杂度为 O(n√n) 我们要先保证通过 [ l , r ] 求得 [ l , r + 1 ] , [ l , r - 1 ] ...
- BZOJ 2743: [HEOI2012]采花 [树状数组 | 主席树]
题意: 查询区间中出现次数$>2$的颜色个数 一眼主席树,区间中$l \le last[i] \le r$的个数减去$l \le last[last[i]] \le r$的个数,搞两颗主席树来做 ...
- HDU 3333 Turing Tree(树状数组/主席树)
题意 给定一个长度为 \(n\) 的序列,\(m\) 个查询,每次查询区间 \([L,R]\) 范围内不同元素的和. \(1\leq T \leq 10\) \(1 \leq n\leq 300 ...
- 【模板】【P3605】【USACO17JAN】Promotion Counting 晋升者计数——动态开点和线段树合并(树状数组/主席树)
(题面来自Luogu) 题目描述 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者! 为了方便,把奶牛从 1⋯N(1≤N≤100,000) 编号,把公司组织成一棵树 ...
随机推荐
- react初探索--react + react-router + ant-design 后台管理系统配置
首先确认安装了node环境,Node >= 6. 如果对react 及 ant-design 一无所知,建议去阅读下api文档,react 可以在 codePen 在线练习. react Api ...
- php扩展1:filp/whoops(用于调试,方便定位错误点)
一.composer下载filp/whoops: 1.在composer.json中添加:"filp/whoops": "*",如下所示: 2.执行compos ...
- winform ComboBox/TextBox自动提示
ComboBox和TextBox控件都带有自动前缀匹配,只要设置其中的AutoCompleteMode,AutoCompleteSource,AutoCompleteCustomSource三个属性的 ...
- PHP 反射API
出处:http://blog.csdn.net/hguisu/article/details/7357421 PHP5添加了一项新的功能:Reflection.这个功能使得phper可以reverse ...
- windows开启远程
windows开启远程桌面超级简单,跟linux相比太简单了. 补充:有瑕疵,应该是远程中的远程桌面属性打钩,但是W8.1没有这个选项,W7可以,其次创建一个管理员账户,身份是管理员,不是标准用户,要 ...
- 【存储过程】MySQL存储过程/存储过程与自定义函数的区别
---------------------------存储过程-------------------- 语法: 创建存储过程: CREATE [definer = {user|current_user ...
- Linux下汇编语言学习笔记5 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...
- poj_2586_Y2K Accounting Bug_201407211318
Y2K Accounting Bug Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10210 Accepted: 50 ...
- KMP算法 C#实现 字符串查找简单实现
KMP算法 的C#实现,初级版本 static void Main(string[] args) { #region 随机字符 StringBuilder sb = new StringBuilder ...
- TCP/IP学习笔记(3)----IP,ARP,RARP协议
把这三个协议放到一起学习是因为这三个协议处于同一层(网络层协议),ARP协议用来找到目标主机的Ethernet网卡Mac地址,IP则承载要发送的消息.数据链路层可以从ARP得到数据的传送信息,而从IP ...