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> ...
随机推荐
- iOS -- MBProgressHUB
高级: http://www.jianshu.com/p/485b8d75ccd4 //只有小菊花 - (void)indeterminateExample { // Show the HUD on ...
- [Algorithms] Sort an Array with a Nested for Loop using Insertion Sort in JavaScript
nsertion sort is another sorting algorithm that closely resembles how we might sort items in the phy ...
- update tableView contenSize
NSIndexPath *messageIndexPath = [NSIndexPath indexPathForRow:afterRowCount-1 inSection:0]; [self. ...
- vue2 less less-loader 的用法
LESS基础语法 我们一起来学习一下LESS的基础语法,LESS的基础语法基本上分为以下几个方面:变量.混合(Mixins).嵌套规则.运算.函数.作用域等.这些基础语法需要我们先牢牢的掌握住,然后才 ...
- 【iOS】UIWebView的HTML5扩展之canvas篇
先前公布大那个所谓的"HTML5"扩展严格说来还算不是"HTML5".曲曲几行JS代码就自诩为HTML5扩展多少有些标题党的嫌疑. 而相比之下,本篇的主题can ...
- 设置安卓开机动画、开机logo
我们要修改的是system>media文件夹下的bootanimation.zip(手机开机动画)这个文件 先来讲讲这个文件结构:该zip解压后得到两个文件, 第一个目录存放了开机时播放的图片( ...
- EasyUI基础入门之Droppable(可投掷)
怎么说呢Droppable这个单词究竟是什么意思,准确来说easyui作者究竟要表达什么意思,还是不大好拿捏的.只是没关系,没有必要纠结与这些细枝末节的东西,依据官网的demo效果,就简单的将之定义为 ...
- 构建基于Javascript的移动web CMS——Hello,World
在一篇构建基于Javascript的移动web CMS入门--简单介绍中简单的介绍了关于墨颀CMS的一些原理,其极框架组成.于是開始接着应该说明一下这个CMS是怎样一步步搭建起来. RequireJS ...
- uboot下载地址
非常奇怪百度搜索都搜不到一个好的uboot下载的说明,仅此标记 HOME http://www.denx.de/wiki/U-Boot/SourceCode sourcecode http://www ...
- docker&k8s填坑记
本篇主要用于记录在实施docker和kubenetes过程中遇到的一个问题和解决办法. 本节部分内容摘自互联网,有些部分为自己在测试环境中遇到到实际问题,后面还会根据实际情况不断分享关于docker/ ...