洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大
我们将线段树套在树状数组上,查询前预处理出所有要一起移动的节点编号,并在查询过程中一起将这些节点移到左右子树上。
Code:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 6000000 + 5;
int A[maxn], arr[maxn];
int n, m, cnt;
struct Queries
{
int c, l, r, k;
Queries(int c = 0, int l = 0, int r = 0, int k = 0):c(c), l(l), r(r), k(k) {}
}asks[maxn];
struct Segment_Tree
{
int lson[maxn * 10], rson[maxn * 10], root[maxn], temp[2][200], count[2], sumv[maxn * 10];
int cnt_Tree;
inline int lowbit(int t)
{
return t & (-t);
}
void insert(int l, int r, int pos, int delta, int &o)
{
if(!o) o = ++cnt_Tree;
sumv[o] += delta;
if(l == r) return;
int mid = (l + r) >> 1;
if(pos <= mid)
insert(l, mid, pos, delta, lson[o]);
else
insert(mid + 1, r, pos, delta, rson[o]);
}
inline void update(int pos, int val, int delta)
{
for(int i = pos;i <= n; i += lowbit(i))
insert(1, n, val, delta, root[i]);
}
int query(int l, int r, int k)
{
if(l == r) return l;
int sum = 0;
for(int i = 1;i <= count[0]; ++i) sum += sumv[lson[temp[0][i]]];
for(int i = 1;i <= count[1]; ++i) sum -= sumv[lson[temp[1][i]]];
int mid = (l + r) >> 1;
if(k <= sum) {
for(int i = 1;i <= count[0]; ++i) temp[0][i] = lson[temp[0][i]];
for(int i = 1;i <= count[1]; ++i) temp[1][i] = lson[temp[1][i]];
return query(l, mid, k);
}
else
{
for(int i = 1;i <= count[0]; ++i) temp[0][i] = rson[temp[0][i]];
for(int i = 1;i <= count[1]; ++i) temp[1][i] = rson[temp[1][i]];
return query(mid + 1, r, k - sum);
}
}
inline int Query(int l, int r, int k)
{
memset(temp, 0, sizeof(temp));
count[0] = count[1] = 0;
for(int i = r;i >= 1;i -= lowbit(i))
temp[0][++count[0]] = root[i];
for(int i = l - 1;i >= 1;i -= lowbit(i))
temp[1][++count[1]] = root[i];
return query(1, n, k);
}
}T;
inline int get(int a)
{
return lower_bound(A + 1, A + 1 + cnt, a) - A;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n; ++i)
{
scanf("%d",&arr[i]);
A[i] = arr[i];
}
cnt = n;
for(int i = 1;i <= m; ++i)
{
char opt[3];
scanf("%s",opt);
if(opt[0] == 'Q')
{
int a, b, c;
scanf("%d%d%d",&a,&b,&c);
asks[i] = Queries(0, a, b, c);
}
if(opt[0] == 'C')
{
int a, b;
scanf("%d%d",&a,&b);
asks[i] = Queries(1, a, a, b);
A[++cnt] = b;
}
}
n = cnt;
sort(A + 1, A + 1 + cnt);
for(int i = 1;i <= n; ++i)
{
int cur_num = get(arr[i]);
T.update(i, cur_num, 1);
}
for(int i = 1;i <= m; ++i)
{
if(asks[i].c)
{
int origin_num = get(arr[asks[i].l]);
T.update(asks[i].l, origin_num, -1);
int cur_num = get(asks[i].k);
T.update(asks[i].l, cur_num, 1);
arr[asks[i].l] = asks[i].k;
}
else printf("%d\n", A[T.Query(asks[i].l, asks[i].r, asks[i].k)]);
}
return 0;
}
洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大的更多相关文章
- 洛谷P2617 Dynamic Rankings (主席树)
洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...
- luogu P2617 Dynamic Rankings && bzoj 1901 (带修改区间第k大)
链接:https://www.luogu.org/problemnew/show/P2617 思路: 如果直接在主席树上修改的话,每次修改都会对后面所有的树造成影响,一次修改的复杂度就会变成 : n* ...
- 2018.07.01洛谷P2617 Dynamic Rankings(带修主席树)
P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i ...
- 洛谷 P2617 Dynamic Rankings || ZOJ - 2112
写的让人看不懂,仅留作笔记 静态主席树,相当于前缀和套(可持久化方法构建的)值域线段树. 建树方法:记录前缀和的各位置的线段树的root.先建一个"第0棵线段树",是完整的(不需要 ...
- 洛谷 P2617 Dynamic Rankings 解题报告
P2617 Dynamic Rankings 题目描述 给定一个含有\(n\)个数的序列\(a[1],a[2],a[3],\dots,a[n]\),程序必须回答这样的询问:对于给定的\(i,j,k\) ...
- 洛谷P2617 Dynamic Rankings
带修主席树模板题 主席树的单点修改就是把前缀和(大概)的形式改成用树状数组维护,每个树状数组的元素都套了一个主席树(相当于每个数组的元素root[i]都是主席树,且这个主席树维护了(i - lowbi ...
- ZOJ -2112 Dynamic Rankings 主席树 待修改的区间第K大
Dynamic Rankings 带修改的区间第K大其实就是先和静态区间第K大的操作一样.先建立一颗主席树, 然后再在树状数组的每一个节点开线段树(其实也是主席树,共用节点), 每次修改的时候都按照树 ...
- 洛谷$P2617\ Dynamic\ Rankings$ 整体二分
正解:整体二分 解题报告: 传送门$w$ 阿查询带修区间第$k$小不显然整体二分板子呗,,, 就考虑先按时间戳排序(,,,其实并不需要读入的时候就按着时间戳排的鸭$QwQ$ 每次二分出$mid$先把所 ...
- BZOJ1901 Zju2112 Dynamic Rankings 主席树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1901 题意概括 给你一段序列(n个数),让你支持一些操作(共m次), 有两种操作,一种是询问区间第 ...
随机推荐
- thrift - C#(CSharp)客户端连接池(ConnectionPool)
调用示例: var tran = ThriftPool.Instance().BorrowInstance(); TProtocol protocol = new TBinaryProtoco ...
- win7(32位)旗舰版共享HP1010打印机给WINXP专业版
一.状况: 两台电脑,同一网段内,电脑A是WIN7系统(32位),电脑B是WINXP系统. ①电脑A(win7)已经安装完打印机驱动,能正常打印,对该打印机HP1010共享时,提示“无法保存打印机设置 ...
- oc与swift比较
swift试是用语言层面的雕虫小技和oc的机制大道进行pk. 从整体上来说,oc是一个更加优秀的语言.
- NodeJS加密算法(转)
nodejs中常用加密算法 1.Hash算法加密: 创建一个nodejs文件hash.js,输入内容如下: 1 var crypto = require('crypto'); //加载crypto ...
- Vue中的坑
今天给大家总结了Vue中的坑,都是平常踩到的,希望对大家有所帮助 1.vuex的一个“坑” 报错原因:在使用Vuex的时候在main.js中引入的时候对名字的大小写有区别 解决法案: 错误写法: 正确 ...
- luogu 自适应Simpson1
自适应simpson1 题意 求一个定积分 (可以手推公式,但是我不想推怎么办) 解法 用一个又一个的二次函数覆盖原函数,则可以近似的得到原函数的积分.(这就是Simpson) 模板在下面: #inc ...
- [CodeForces]1006F Xor Path
双向搜索. 水div3的时候最后一道题由于C题死活看不懂题 来不及做F了Orz.. 因为n,m是20,双向搜索一下,求个到中间的Xor值的方案,统计一下即可. 时间复杂度\(O(2^{21})\) 好 ...
- Linux mysql-5.7.17安装 教程
1.下载安装文件 #mkdir /data #mkdir /data/software #cd /data/software #wget http://dev.mysql.com/get/Downl ...
- STM32 HAL库使用中断实现串口接收不定长数据
以前用DMA实现接收不定长数据,DMA的方法接收串口助手的数据,全部没问题,不过如果接收模块返回的数据,而这些数据如果包含回车换行的话就会停止接收,例如接收:AT\r\nOK\r\n,就只能接收到AT ...
- Spring配置文件中指定init-method属性的作用
bean 配置文件属性 init-method 用于在bean初始化时指定执行方法,用来替代继承 InitializingBean接口.相关链接:https://www.cnblogs.com/Joe ...