[ZJU 2112] Dynamic Rankings
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1901
[算法]
首先 , 考虑没有修改操作
不妨建立可持久化线段树 , 第i棵树维护区间[1 , i]中的数的出现个数 , 则可以通过在线段树上二分的方式求出答案
那么 , 若有修改操作 , 我们不妨使用树状数组套可持久化线段树
树状数组中的第i个元素为一棵可持久化线段树 , 代表区间[i , i - lowbit(i) + 1]每个数的出现次数
询问时可以同样二分 , 只需用最多log(N)棵线段树作差即可
时间复杂度 : O(NlogN ^ 2)
[代码]
#include<bits/stdc++.h>
using namespace std;
#define MAXN 200010
#define MAXP 5000010
#define MAXLOG 20
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; int n , m , len , L , R;
int a[MAXN] , root[MAXN] , val[MAXN] , x[MAXN] , y[MAXN] , l[MAXN] , r[MAXN] , k[MAXN] , ql[MAXLOG] , qr[MAXLOG];
char type[MAXN][]; struct Presitent_Segment_Tree
{
int sz;
int sum[MAXP] , lson[MAXP] , rson[MAXP];
Presitent_Segment_Tree()
{
sz = ;
memset(root , , sizeof(root));
memset(lson , , sizeof(lson));
memset(rson , , sizeof(rson));
}
inline void modify(int &k , int old , int l , int r , int pos , int value)
{
k = ++sz;
lson[k] = lson[old] , rson[k] = rson[old];
sum[k] = sum[old] + value;
if (l == r) return;
int mid = (l + r) >> ;
if (mid >= pos) modify(lson[k] , lson[k] , l , mid , pos , value);
else modify(rson[k] , rson[k] , mid + , r , pos , value);
}
inline int query(int l , int r , int k)
{
int cnt = ;
if (l == r)
return l;
for (int i = ; i <= L; i++) cnt -= sum[lson[ql[i]]];
for (int i = ; i <= R; i++) cnt += sum[lson[qr[i]]];
int mid = (l + r) >> ;
if (cnt >= k)
{
for (int i = ; i <= L; i++) ql[i] = lson[ql[i]];
for (int i = ; i <= R; i++) qr[i] = lson[qr[i]];
return query(l , mid , k);
} else
{
for (int i = ; i <= L; i++) ql[i] = rson[ql[i]];
for (int i = ; i <= R; i++) qr[i] = rson[qr[i]];
return query(mid + , r , k - cnt);
}
}
} PST;
struct Binary_Indexed_Tree
{
inline int lowbit(int x)
{
return x & (-x);
}
inline void modify(int pos , int x , int val)
{
for (int i = pos; i <= n; i += lowbit(i))
PST.modify(root[i] , root[i] , , len , x , val);
}
inline int query(int l , int r , int k)
{
L = , R = ;
for (int i = l - ; i; i -= lowbit(i))
ql[++L] = root[i];
for (int i = r; i; i -= lowbit(i))
qr[++R] = root[i];
return PST.query( , len , k);
}
} BIT; template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
} int main()
{ scanf("%d%d" , &n , &m);
len = n;
for (int i = ; i <= n; i++)
{
scanf("%d" , &a[i]);
val[i] = a[i];
}
for (int i = ; i <= m; i++)
{
scanf("%s" , type[i]);
if (type[i][] == 'C')
{
scanf("%d%d" , &x[i] , &y[i]);
val[++len] = y[i];
} else
scanf("%d%d%d" , &l[i] , &r[i] , &k[i]);
}
sort(val + , val + len + );
len = unique(val + , val + len + ) - val - ;
for (int i = ; i <= n; i++) a[i] = lower_bound(val + , val + len + , a[i]) - val;
for (int i = ; i <= m; i++)
if (type[i][] == 'C') y[i] = lower_bound(val + , val + len + , y[i]) - val;
for (int i = ; i <= n; i++) BIT.modify(i , a[i] , );
for (int i = ; i <= m; i++)
{
if (type[i][] == 'C')
{
BIT.modify(x[i] , a[x[i]] , -);
BIT.modify(x[i] , y[i] , );
a[x[i]] = y[i];
} else printf("%d\n" , val[BIT.query(l[i] , r[i] , k[i])]);
} return ;
}
[ZJU 2112] Dynamic Rankings的更多相关文章
- BZOJ 1901 Zju 2112 Dynamic Rankings 与更改的树董事长
标题效果:给定一个序列,单点变化,询价区间k大. 思维:假设没有变化.然后划分树就可以解决,但树的分工仍然是一棵树,它不支持的变化. 主席舒变化实际上是在外带fenwick右护套层值段树,但正确的值线 ...
- 整体二分&cdq分治 ZOJ 2112 Dynamic Rankings
题目:单点更新查询区间第k大 按照主席树的思想,要主席树套树状数组.即按照每个节点建立主席树,然后利用树状数组的方法来更新维护前缀和.然而,这样的做法在实际中并不能AC,原因即卡空间. 因此我们采用一 ...
- ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...
- 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )
在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...
- 整体二分(SP3946 K-th Number ZOJ 2112 Dynamic Rankings)
SP3946 K-th Number (/2和>>1不一样!!) #include <algorithm> #include <bitset> #include & ...
- ZOJ 2112 Dynamic Rankings(主席树の动态kth)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 The Company Dynamic Rankings ...
- zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap
Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...
- ZOJ 2112 Dynamic Rankings(带修改的区间第K大,分块+二分搜索+二分答案)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大
Dynamic Rankings 带修改的区间第K大其实就是先和静态区间第K大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...
随机推荐
- 【转载】Linux下套接字学习
感觉这个系列还不错,学习一下. 先看的是第三篇: http://blog.csdn.net/gatieme/article/details/46334337 < Linux下套接字详解(三)-- ...
- 【转载】Spark学习——入门
要学习分布式以及数据分析.机器学习之类的,觉得可以通过一些实际的编码项目入手.最近Spark很火,也有不少招聘需要Spark,而且与传统的Hadoop相比,Spark貌似有一些优势.所以就以Spark ...
- Android——滑动事件冲突解决
android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件. android系统中的每个View的子类都具有下面三个与TouchEvent处理密切相关的方法: (1) ...
- 2014年8月25日,收藏家和杀手——面向对象的C++和C(一)
近期事情特别多,睡眠也都非常晚,有点精神和身体混乱的感觉,所以想写写技术分析文章.让两者的我都调整一下.这篇技术分析文章是一直想写的,当前仅仅是开篇,有感觉的时候就写写,属于拼凑而成,兴许的篇章没有时 ...
- tail 监控日志文件
ail命令可以输出文件的尾部内容,默认情况下它显示文件的最后十行.它常用来动态监视文件的尾部内容的增长情况,比如用来监视日志文件的变化.与tail命令对应的是head命令,用来显示文件头部内容. 常用 ...
- svn 命令个
svn 命令行下常用的几个命令 标签: svnpathdelete工作urlfile 2011-11-28 08:16 128627人阅读 评论(1) 收藏 举报 分类: 版本控制(8) 版权声明 ...
- ok6410[001] Ubuntu 16.04[64bit]嵌入式交叉编译环境arm-linux-gcc搭建过程图解
开发PC:Ubuntu16.04.1 开发板:OK6410[飞凌公司出品] 目标:通过GPIO点亮LED ----------------------------------------------- ...
- Linux驱动经典面试题目
1. linux驱动分类 2. 信号量与自旋锁 3. platform总线设备及总线设备怎样编写 4. kmalloc和vmalloc的差别 5. module_init的级别 6. 加入 ...
- 压力测试工具ab,wrk,locust简介
ab 无疑是目前最常见的压力测试工具.其典型用法如下: shell> ab -k -c 100 -t 10 http://domain/path 其中,参数「c」表示的是并发, 参数「t」表示的 ...
- src/github.com/mongodb/mongo-go-driver/mongo/cursor.go 游标的简洁实用
src/github.com/mongodb/mongo-go-driver/mongo/cursor.go // Copyright (C) MongoDB, Inc. 2017-present./ ...