[luogu2617]Dynamic Rankings
题面在这里
description
动态区间第\(k\)大
data range
\]
solution
前置技能:主席树,静态区间第\(k\)大
注意到主席树的区间维护是通过前缀和来实现的,
修改时需要对所有前缀进行修改,一次复杂度是\(O(nlogn)\),显然会\(TLE\)
树套树(树状数组套线段树???)
于是我们想到把主席树的前缀和维护改成树状数组维护
这样树状数组的每一个节点都代表的是一些权值线段树的前缀和
修改
对于树状数组上要修改的每一棵权值线段树进行修改(需要线段树动态开点),
每次加\(lowbit\)后直接在对应的权值线段树上删原点+插新点即可
需要修改\(O(logn)\)棵权值线段树,时间复杂度为\(O(log^2n)\)
查询
这里我们通过树状数组知道了区间\([l,r]\)的整棵权值线段树
在权值线段树上进行二分;
注意前缀\([1,l]\)和前缀\([1,r]\)在树套树上对应的权值线段树的数量可能不同,
于是我们需要在递归的同时保存这\(O(logn)\)个节点的位置
需要查询\(O(logn)\)棵权值线段树,时间复杂度为\(O(log^2n)\)
那么这道题目我们就很开心地做完啦
code
#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define lowbit(x) (x&-x)
#define pub push_back
#define puf push_front
#define pob pop_back
#define pof pop_front
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e8;
const int N=20010;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
}
il void file(){
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
int n,m,len,a[N],o[N],cnt[2][N],rt[N],tot;char c;
struct query{int opt;int l,r,k;int p,t;}Q[N];
struct node{int v,ls,rs;}t[N*400];
#define mid ((l+r)>>1)
ll query(int l,int r,int k){
if(l==r)return l;RG int sum=0;
for(RG int i=1;i<=cnt[0][0];i++){
sum-=t[t[cnt[0][i]].ls].v;
}
for(RG int i=1;i<=cnt[1][0];i++){
sum+=t[t[cnt[1][i]].ls].v;
}
if(k<=sum){
for(RG int i=1;i<=cnt[0][0];i++)
cnt[0][i]=t[cnt[0][i]].ls;
for(RG int i=1;i<=cnt[1][0];i++)
cnt[1][i]=t[cnt[1][i]].ls;
return query(l,mid,k);
}
else{
for(RG int i=1;i<=cnt[0][0];i++)
cnt[0][i]=t[cnt[0][i]].rs;
for(RG int i=1;i<=cnt[1][0];i++)
cnt[1][i]=t[cnt[1][i]].rs;
return query(mid+1,r,k-sum);
}
}
il void query_tree(int l,int r,int k){
cnt[0][0]=cnt[1][0]=0;
for(RG int i=l-1;i;i-=lowbit(i))
cnt[0][++cnt[0][0]]=rt[i];
for(RG int i=r;i;i-=lowbit(i))
cnt[1][++cnt[1][0]]=rt[i];
printf("%d\n",o[query(1,len,k)]);
}
void modify(int &now,int l,int r,int p,int val){
if(!now)now=++tot;t[now].v+=val;if(l==r)return;
if(p<=mid)modify(t[now].ls,l,mid,p,val);
else modify(t[now].rs,mid+1,r,p,val);
}
il void modify_tree(int p,int val){
RG int x=lower_bound(o+1,o+len+1,a[p])-o;
for(RG int i=p;i<=n;i+=lowbit(i)){
modify(rt[i],1,len,x,val);
}
}
int main()
{
len=n=read();m=read();
for(RG int i=1;i<=n;i++)o[i]=a[i]=read();
for(RG int i=1;i<=m;i++){
c=0;while(c!='Q'&&c!='C')c=getchar();
Q[i].opt=(c=='Q');
if(c=='Q'){
Q[i].l=read();Q[i].r=read();Q[i].k=read();
}
else {Q[i].p=read();Q[i].t=read();o[++len]=Q[i].t;}
}
sort(o+1,o+len+1);len=unique(o+1,o+len+1)-o-1;
for(RG int i=1;i<=n;i++)modify_tree(i,1);
for(RG int i=1;i<=m;i++)
if(!Q[i].opt){
modify_tree(Q[i].p,-1);
a[Q[i].p]=Q[i].t;
modify_tree(Q[i].p,1);
}
else{query_tree(Q[i].l,Q[i].r,Q[i].k);}
return 0;
}
[luogu2617]Dynamic Rankings的更多相关文章
- [Luogu2617]Dynamic Rankings(整体二分)
Luogu 动态区间第K大的整体二分解法 之前学主席树的时候就做了这道题(明明是树套树不是主席树啊),码量挺大而且调了我一个晚上.换成整体二分我半个小时就写完了而且一A. 写起来就是爽. 其实原理很简 ...
- [BZOJ1901][luogu2617]Dynamic Rankings(树状数组+主席树)
题面 单点修改,区间求第k大 分析 首先,这道题卡权值线段树套treap的做法,所以只能用主席树做 对于静态的查询,root[i]对应的主席树的区间[l,r]保存的是a[1]~a[i]有多少个值落在区 ...
- 「luogu2617」Dynamic Rankings
「luogu2617」Dynamic Rankings 传送门 树套树直接上树状数组套主席树,常数很大就是了. 树套树参考代码: /*-------------------------------- ...
- BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7143 Solved: 2968[Su ...
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- [BZOJ1901]Zju2112 Dynamic Rankings
[BZOJ1901]Zju2112 Dynamic Rankings 试题描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i ...
- ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...
- BZOJ-1901 Zju2112 Dynamic Rankings 函数式线段树 套 树状数组+离线处理
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6058 Solved: 2521 [Su ...
- ZOJ 2112 Dynamic Rankings(主席树の动态kth)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 The Company Dynamic Rankings ...
随机推荐
- Apache和Nignx基于三种方式搭建web站点并设置用户访问控制达到优化整个站点性能
个人用户主页: 1:Vim /etc/http/con.d/userdir: UserDir disabled //个人用户主页开启 UserDir public_html //指定 ...
- Jenkins 添加节点 java web方式
环境说明: 主节点:windows server 从节点:两台linux 1. windows server安装jenkins就不多说了,直接添加节点配置如下 2.全局安全配置,指定确认的端口后,记得 ...
- djangorestframework怎么这么好用!
一年前就已经用过restframework, 当时觉得这个只是给web框架打辅助的, 他能实现的我也都实现(可能没有那么好用, 嘿嘿) 但是我有一种东西叫做效率, 时间就是金钱, 别人造好的就直接用就 ...
- Go语言中的HTTP
Go中的http使用 package main import ( "fmt" "net/http" "io/ioutil" "st ...
- BZOJ:2038: [2009国家集训队]小Z的袜子(hose)(莫队算法模板)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2038 解题心得: 第一次接触莫队算法,很神奇,很巧妙.莫队算法主要就是用来解决多次询问时 ...
- 三种urllib实现网页下载,含cookie模拟登陆
coding=UTF-8 import re import urllib.request, http.cookiejar, urllib.parse # # print('-------------- ...
- ip4addr_ntoa和不可重入函数
在网络中,有一个转换IP地址到ASIIC字符串的函数,该函数的返回值所指向的ASIIC字符串驻留在静态内存中,所以该函数不可重入. 通俗的讲,在多任务系统中,一个任务执行在调用运行这个函数的时候,其他 ...
- valgrind检查still reachable情况
valgrind --leak-check=yes检查bufr编解码程序运行时提示still reachable: 568 bytes in 1 blocks,如下图示: 于是怀疑有内存泄漏,难道是m ...
- 【紫书】(UVa12563)Jin Ge Jin Qu hao
继续战dp.不提. 题意分析 这题说白了就是一条01背包问题,因为对于给定的秒数你只要-1s(emmmmm)然后就能当01背包做了——那1s送给劲歌金曲(?).比较好玩的是这里面dp状态的保存——因为 ...
- javaX邮件发送
/** * * * @param mailServerHost 邮件服务器 * @param mailServerPort 端口 * @param validate 是否需要身份验证 * @para ...