墨墨购买了一套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:数颜色(数状数组套主席树)(带修改的莫对)的更多相关文章

  1. ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解

    题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...

  2. 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 ...

  3. bzoj1901--树状数组套主席树

    树状数组套主席树模板题... 题目大意: 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[ ...

  4. BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树

    BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...

  5. [COGS257]动态排名系统 树状数组套主席树

    257. 动态排名系统 时间限制:5 s   内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[ ...

  6. BZOJ 2141 排队(树状数组套主席树)

    解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...

  7. [BZOJ3932] [CQOI2015]任务查询系统(主席树 || 树状数组 套 主席树 + 差分 + 离散化)

    传送门 看到这个题有个很暴力的想法, 可以每一个时间点都建一颗主席树,主席树上叶子节点 i 表示优先级为 i 的任务有多少个. 当 x 到 y 有个优先级为 k 的任务时,循环 x 到 y 的每个点, ...

  8. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  9. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

随机推荐

  1. iOS -- MBProgressHUB

    高级: http://www.jianshu.com/p/485b8d75ccd4 //只有小菊花 - (void)indeterminateExample { // Show the HUD on ...

  2. [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 ...

  3. update tableView contenSize

    NSIndexPath *messageIndexPath = [NSIndexPath indexPathForRow:afterRowCount-1 inSection:0];    [self. ...

  4. vue2 less less-loader 的用法

    LESS基础语法 我们一起来学习一下LESS的基础语法,LESS的基础语法基本上分为以下几个方面:变量.混合(Mixins).嵌套规则.运算.函数.作用域等.这些基础语法需要我们先牢牢的掌握住,然后才 ...

  5. 【iOS】UIWebView的HTML5扩展之canvas篇

    先前公布大那个所谓的"HTML5"扩展严格说来还算不是"HTML5".曲曲几行JS代码就自诩为HTML5扩展多少有些标题党的嫌疑. 而相比之下,本篇的主题can ...

  6. 设置安卓开机动画、开机logo

    我们要修改的是system>media文件夹下的bootanimation.zip(手机开机动画)这个文件 先来讲讲这个文件结构:该zip解压后得到两个文件, 第一个目录存放了开机时播放的图片( ...

  7. EasyUI基础入门之Droppable(可投掷)

    怎么说呢Droppable这个单词究竟是什么意思,准确来说easyui作者究竟要表达什么意思,还是不大好拿捏的.只是没关系,没有必要纠结与这些细枝末节的东西,依据官网的demo效果,就简单的将之定义为 ...

  8. 构建基于Javascript的移动web CMS——Hello,World

    在一篇构建基于Javascript的移动web CMS入门--简单介绍中简单的介绍了关于墨颀CMS的一些原理,其极框架组成.于是開始接着应该说明一下这个CMS是怎样一步步搭建起来. RequireJS ...

  9. uboot下载地址

    非常奇怪百度搜索都搜不到一个好的uboot下载的说明,仅此标记 HOME http://www.denx.de/wiki/U-Boot/SourceCode sourcecode http://www ...

  10. docker&k8s填坑记

    本篇主要用于记录在实施docker和kubenetes过程中遇到的一个问题和解决办法. 本节部分内容摘自互联网,有些部分为自己在测试环境中遇到到实际问题,后面还会根据实际情况不断分享关于docker/ ...