1A啊,激动。

首先,不修改的情况下可以直接用主席树搞,修改的话,直接用主席树搞一次修改的情况下复杂度是O(nlogn)的。

就像你要求区间和一样,用前缀和查询是O(1),修改是O(n),只不过主席树是前缀和套权值线段树,每个操作乘个logn。

如果用树状数组来维护区间和,查询是O(logn),修改是O(logn),那么用树状数组套权值线段树,每个操作就是O(log^2n).

由于这道题还需要修改 改动一个数的前驱和后继。用set搞一搞。

# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-
# define MOD
# define INF
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<,l,mid
# define rch p<<|,mid+,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
int res=, flag=;
char ch;
if((ch=getchar())=='-') flag=;
else if(ch>=''&&ch<='') res=ch-'';
while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
return flag?-res:res;
}
void Out(int a) {
if(a<) {putchar('-'); a=-a;}
if(a>=) Out(a/);
putchar(a%+'');
}
const int N=;
//Code begin... struct Node{int l, r; bool flag;}node[N];
int a[N], vis[N<<], to[N], sz, n;
int root[N], ls[N*], rs[N*], s[N*];
VI v;
set<int>mt[N<<];
set<int>::iterator it; void update(int l, int r, int x, int &y, int z, int val){
y=++sz;
s[y]=s[x]+val;
if (l==r) return ;
ls[y]=ls[x]; rs[y]=rs[x];
int mid=(l+r)>>;
if (z<=mid) update(l,mid,ls[x],ls[y],z,val);
else update(mid+,r,rs[x],rs[y],z,val);
}
int query(int l, int r, int x, int L){
if (r<L) return ;
if (l>=L) return s[x];
int mid=(l+r)>>;
return query(l,mid,ls[x],L)+query(mid+,r,rs[x],L);
}
void add(int x, int y, int val){
for (int i=x; i<=n; i+=lowbit(i)) update(,n+,root[i],root[i],y,val);
}
int sum(int x, int val){
int res=;
for (int i=x; i; i-=lowbit(i)) res+=query(,n+,root[i],val);
return res;
}
int main ()
{
int m, tmp;
char flag[];
scanf("%d%d",&n,&m);
FOR(i,,n) scanf("%d",a+i), v.pb(a[i]);
FOR(i,,m) {
scanf("%s%d%d",flag,&node[i].l,&node[i].r);
if (flag[]=='Q') node[i].flag=true;
else v.pb(node[i].r);
}
sort(v.begin(),v.end());
int siz=unique(v.begin(),v.end())-v.begin();
FOR(i,,n) {
a[i]=lower_bound(v.begin(),v.begin()+siz,a[i])-v.begin()+;
if (vis[a[i]]) to[vis[a[i]]]=i;
vis[a[i]]=i;
mt[a[i]].insert(i);
}
FOR(i,,n) if (!to[i]) to[i]=n+;
FOR(i,,n) add(i,to[i],);
FOR(i,,m) {
if (node[i].flag) printf("%d\n",sum(node[i].r,node[i].r+)-sum(node[i].l-,node[i].r+));
else {
node[i].r=lower_bound(v.begin(),v.begin()+siz,node[i].r)-v.begin()+;
it=mt[a[node[i].l]].lower_bound(node[i].l);
++it;
if (it==mt[a[node[i].l]].end()) tmp=n+;
else tmp=*it;
add(node[i].l,tmp,-);
--it;
if (it!=mt[a[node[i].l]].begin()) --it, add(*it,node[i].l,-), add(*it,tmp,);
mt[a[node[i].l]].erase(node[i].l);
a[node[i].l]=node[i].r;
it=mt[node[i].r].lower_bound(node[i].l);
if (it==mt[node[i].r].end()) tmp=n+;
else tmp=*it;
add(node[i].l,tmp,);
if (it!=mt[node[i].r].begin()) --it, add(*it,tmp,-), add(*it,node[i].l,);
mt[node[i].r].insert(node[i].l);
}
}
return ;
}

BZOJ 2120 数颜色(树状数组套主席树)的更多相关文章

  1. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  10. P2617 Dynamic Rankings(树状数组套主席树)

    P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...

随机推荐

  1. 20154327 Exp2 后门原理与实践

    实践内容 使用netcat和socat.msf-meterpreter等工具获得主机权限,并进行一些恶意行为,如监控摄像头.记录键盘输入.截屏等. 详情见实验指导书 实践过程 netcat netca ...

  2. linux进程的学习笔记(未完)

    1. 进程是程序执行的一个实例,如果16个用户同时运行vi,那么有16个独立的进程,尽管它们共享同一个可执行代码,问题在于FreeRTOS这种系统,是否可以建2个相同的任务,需要注意什么?在linux ...

  3. WebService-CXF使用

    一.SOAP和WSDL概念: SOAP(Simple Object Access Protocol):简单对象访问协议 SOAP作为一个基于XML语言的协议用于在网上传输数据 SOAP=在Http的基 ...

  4. ElasticSearch搜索引擎安装配置中文分词器IK插件

    近几篇ElasticSearch系列: 1.阿里云服务器Linux系统安装配置ElasticSearch搜索引擎 2.Linux系统中ElasticSearch搜索引擎安装配置Head插件 3.Ela ...

  5. 跟浩哥学自动化测试Selenium -- 浏览器的基本操作与元素定位(3)

    浏览器的基本操作与元素定位 通过上一章学习,我们已经学会了如何设置驱动路径,如何创建浏览器对象,如何打开一个网站,接下来我们要进行一些复杂的操作比如先打开百度首页,在打开博客园,网页后退,前进等等,甚 ...

  6. Siki_Unity_2-10_数据结构与算法

    Unity 2-10 数据结构与算法 任务1-1:数据结构简介 数据结构:数据存储的结构,数据之间的关系 数据结构分类: 集合:同属于一个集合 线性结构:数据元素存在一对一的关系 树形结构:数据元素存 ...

  7. GIT: 分布式开发 代码管理工具使用命令大全

    代码管理工具: GIT     什么是GIT? Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目 Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常 ...

  8. leetcode-组合总数III(回溯)

    组合总和 III 找出所有相加之和为 n 的 k 个数的组合.组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字. 说明: 所有数字都是正整数. 解集不能包含重复的组合.  示例 ...

  9. 单元测试模块unittest使用学习

    工作原理: unittest中最核心的四个概念是:test case, test suite, test runner, test fixture. 一个TestCase的实例就是一个测试用例.什么是 ...

  10. Apache——SSL协议

    SSL 协议既用到了公钥加密技术又用到了对称加密技术,对称加密技术虽然比公钥加密技术的速度快,可是公钥加密技术提供了更好的身份认证技术.SSL 的握手协议非常有效的让客户和服务器之间完成相互之间的身份 ...