洛谷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次), 有两种操作,一种是询问区间第 ...
随机推荐
- 微信小程序调试 Webview
document.querySelectorAll("webview")[1].showDevTools(true);
- CDR X7 限时3折618年中大促,是时候出手了!
力量与激情.胜利与喜悦,这些自带饱满情绪的词,即将“刷屏”这个夏天!32支球队,28个不眠夜,你将与谁度过? 一场视觉上的饕餮盛宴即将开始! 小编也是个疯狂足球迷,虽然中国队无缘今年的俄罗斯世界杯,但 ...
- [LUOGU]3919 【模板】可持久化数组
用可持久化线段树维护可持久化数组.可持久化线段树见之前发的主席树模板 #include <iostream> #include <cstdio> #include <cs ...
- ansible 工作原理以及使用详解
内容:1.ansible的作用以及工作结构2.ansible的安装以及使用3.ansible的playbook使用 一.ansible的作用以及工作结构 1.ansible简介: ...
- python3编写登录接口
#/usr/bin/env python#yehui'''作业一:博客 作业二:编写登陆接口 输入用户名密码 认证成功后显示欢迎信息 输错三次后锁定'''import getpass, os, pic ...
- 利用 ST-LINK Utility软件下载程序
先在电脑上安装STM32 ST-LINK Utility,软件安装一路Next就可以了,安装好软件之后界面如下: 下载程序只需要使用3个图标就可以了 第一个图标Connect to the ta ...
- Ajax得到JSON数据
Ajax得到JSON数据
- 华硕VX50V开机老是进入bios
问题:华硕VX50V开机老是进入bios 如图: 解决办法: 1.将 Boot 中的--->> Lunch CSM ---->>设置为 -->> ena ...
- soapUI 5.1.2 下载以及破解
转:https://blog.csdn.net/weiqing723/article/details/78865734
- ZOJ 3329
方程很明显有 d[i]=sum(pk*d[i+k])+p0*d[0]; 其中pi可以在开始时枚举求出. 设d[i]=A[i]*d[0]+B[i], 代入上式 d[i]=(sum(pk*A[i+k])+ ...