BZOJ2120:数颜色(数状数组套主席树)(带修改的莫对)
墨墨购买了一套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 Input6 5 1 2 3 4 5 5 Q 1 4 Q 2 6 R 1 2 Q 1 4 Q 2 6
Sample Output4 4 3 4 Hint
对于100%的数据,N≤10000,M≤10000,修改操作不多于1000次,所有的输入数据中出现的所有整数均大于等于1且不超过10^6。
思路: 假如没有修改操作,就是很常见的主席树求区间不同数的个数:把下边i看成x轴,对用的前缀pre[i]看成y轴,然后就可以用主席树求矩形内(s轴范围的[L,R],y轴范围的[0,L-1])的点的个数。 考虑修改操作,因为主席树只用到差分,我们想到可以用数状数组求前缀和差分。那么把普通的主席树转化为数状数组套主席树:对于每个x=i,我们加一个点,等效于y=[pre[i],N]范围都加1。即用数状数组表示为:
for(j=i;j<=N;j+=(-j)&j) add(rt[j],,tN,Laxt[a[i]],);//即对于的主席树都更改,达到记录前缀和的效果。
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
struct in{ int l,r,sum; }p[maxn];
int a[maxn],b[maxn],Laxt[maxn],x[maxn],y[maxn],rt[maxn];
int N,M,tN,cnt; char c[maxn][];
set<int>s[maxn];
set<int>::iterator it,pre,lat;
void add(int &Now,int L,int R,int pos,int val)
{
if(!Now) Now=++cnt; p[Now].sum+=val;
if(L==R) return ; int Mid=(L+R)>>;
if(pos<=Mid) add(p[Now].l,L,Mid,pos,val);
else add(p[Now].r,Mid+,R,pos,val);
}
int query(int Now,int L,int R,int l,int r)
{
if(l<=L&&r>=R) return p[Now].sum;
int res=,Mid=(L+R)>>;
if(l<=Mid) res+=query(p[Now].l,L,Mid,l,r);
if(r>Mid) res+=query(p[Now].r,Mid+,R,l,r);
return res;
}
int main()
{
int i,j; scanf("%d%d",&N,&M);
for(i=;i<=N;i++) scanf("%d",&a[i]),b[++tN]=a[i];
for(i=;i<=M;i++){
scanf("%s%d%d",c[i],&x[i],&y[i]);
if(c[i][]=='R') b[++tN]=y[i];
}
sort(b+,b+tN+);
tN=unique(b+,b+tN+)-(b+);
for(i=;i<=N;i++) {
a[i]=lower_bound(b+,b+tN+,a[i])-b;
for(j=i;j<=N;j+=(-j)&j) add(rt[j],,tN,Laxt[a[i]],);
s[a[i]].insert(i); Laxt[a[i]]=i;
}
for(i=;i<=tN;i++) s[i].insert();
for(i=;i<=M;i++){
if(c[i][]=='Q'){
int ans=;
for(j=y[i];j;j-=(-j)&j) ans+=query(rt[j],,tN,,x[i]-);
for(j=x[i]-;j;j-=(-j)&j) ans-=query(rt[j],,tN,,x[i]-);
printf("%d\n",ans);
}
else {
y[i]=lower_bound(b+,b+tN+,y[i])-b;
if(a[x[i]]==y[i]) continue;
it=pre=lat=s[a[x[i]]].lower_bound(x[i]); pre--; lat++;
for(j=x[i];j<=N;j+=(-j)&j) add(rt[j],,tN,*pre,-);
if(lat!=s[a[x[i]]].end()) {
for(j=*lat;j<=N;j+=(-j)&j) add(rt[j],,tN,x[i],-);
for(j=*lat;j<=N;j+=(-j)&j) add(rt[j],,tN,*pre,);
} s[a[x[i]]].erase(it); a[x[i]]=y[i]; s[a[x[i]]].insert(x[i]); it=pre=lat=s[a[x[i]]].lower_bound(x[i]); pre--; lat++;
for(j=x[i];j<=N;j+=(-j)&j) add(rt[j],,tN,*pre,);
if(lat!=s[a[x[i]]].end()) {
for(j=*lat;j<=N;j+=(-j)&j) add(rt[j],,tN,x[i],);
for(j=*lat;j<=N;j+=(-j)&j) add(rt[j],,tN,*pre,-);
}
}
}
return ;
}
(当然还可以用带修改的莫对来做,日后再补!)
BZOJ2120:数颜色(数状数组套主席树)(带修改的莫对)的更多相关文章
- ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解
题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...
- Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)
E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...
- bzoj1901--树状数组套主席树
树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...
- BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树
BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...
- [COGS257]动态排名系统 树状数组套主席树
257. 动态排名系统 时间限制:5 s 内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[ ...
- BZOJ 2141 排队(树状数组套主席树)
解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...
- [BZOJ3932] [CQOI2015]任务查询系统(主席树 || 树状数组 套 主席树 + 差分 + 离散化)
传送门 看到这个题有个很暴力的想法, 可以每一个时间点都建一颗主席树,主席树上叶子节点 i 表示优先级为 i 的任务有多少个. 当 x 到 y 有个优先级为 k 的任务时,循环 x 到 y 的每个点, ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
随机推荐
- vim 树形菜单插件NERDTree 的安装
vim 树形菜单插件的安装 NERDTree 1. mkdir ~/.vim cd ~/.vim mkdir bundle mkdir autoload 2. curl -Sso ~/.vim/au ...
- Odoo 运费
模块delievery可以将运费Charge给客户 安装delivery模块 Delivery method 在做订单的时候,选择相应的运输方法, 系统 ...
- Kick the ball!(dfs)湖南省赛第十届
Problem K: Kick the ball! Time Limit: 1 Sec Memory Limit: 128 MB Special Judge Submit: 109 Solved ...
- ubuntu下调试ffmpeg程序出现undefined reference to pthread_once ,undefined reference to uncompress错误
Ubuntu(版本16.04)下默认配置编译Ffmpeg(版本4.1.3configure 添加选项--enable-threads),将编译好的ffmpeg库添加到程序 中进行编译出现undefin ...
- [Codevs 1230]元素查找(手写哈希表)
题目连接:http://codevs.cn/problem/1230/ 说白了就是要我们自己手写一个哈希表的数据结构来实现加入和查找功能.map也能直接过(我第一次写就是用map骗AC的) 提一下个人 ...
- SubmittingPatches, SubmitChecklist and CodingStyle
How to Get Your Change Into the Linux Kernel or Care And Operation Of Your Linus Torvalds For a pers ...
- SWIM接口及STM8烧录过程
1. 硬件连接 SWIM接口只需要一根传输线,即可完成双向的传输.传输过程,都是由主控制端(host)发起,设备端然后做出反应.host端需要在一个总线上实现读和写,那就是说必须要同时接一个输出IO和 ...
- 用redis实现跨服务器session(转)
这个月我们新开发了一个项目,由于使用到了4台机器做web,使用dns做负载均衡, 上面图上用户通过DNS的调度(一个域名对应多个ip)分别访问到VM2-VM5上,四台机器都访问VM1上的redis,两 ...
- angular 指令封装弹出框效果
就直接用bs的警告框啦~,Duang~ 功能 可以设置message和type,type就是bs内置的几种颜色 默认提示3秒框自动关闭,或者点击x号关闭 代码 模板 <div class=&qu ...
- 命令行查看memcached的运行状态(转载)
很多时候需要监控服务器上的Memcached运行情况,比如缓存的查询次数,命中率之类的.但找到的那个memcached-tool是linux下用perl写的,我也没试过windows能不能用.后来发现 ...