【BZOJ1901】Dynamic Rankings(树套树,树状数组,主席树)
题意:给定一个N个数的序列,要求维护一个数据结构支持以下两种操作:
1:将第X个数改成Y
2:查询第X到第Y个数里第K小的数是多少
n,m<=10000,a[i]<=10^9
思路:单点修改版本的主席树
对于没有修改的主席树,我们直接在对应的节点上每个点继承上个点的状态,再用链表创建logn个点来表示这个数对t数组的修改
而单点修改不可能把后面的前缀和都加上logn个点
所以就利用树状数组的思想
t是一个树状数组,里面的每个点都是一棵主席树
更改时没有区别
询问时最多可能有logn段区间相减
时间复杂度(Nlogn^2)
var t:array[..]of record
l,r,s:longint;
end;
a,b,root,hash,left,right,flag:array[..]of longint;
d:array[..,..]of longint;
n,m,i,j,q,u,cnt,la,lb,s,tmp:longint;
ch:string; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; function find(k:longint):longint;
var l,r,mid:longint;
begin
l:=; r:=u;
while l<=r do
begin
mid:=(l+r)>>;
if hash[mid]=k then exit(mid);
if hash[mid]<k then l:=mid+
else r:=mid-;
end;
end; procedure qsort(l,r:longint);
var i,j,mid:longint;
begin
i:=l; j:=r; mid:=b[(l+r)>>];
repeat
while mid>b[i] do inc(i);
while mid<b[j] do dec(j);
if i<=j then
begin
swap(b[i],b[j]);
inc(i); dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end; function lowbit(x:longint):longint;
begin
exit(x and (-x));
end; procedure update(l,r:longint;var p:longint;v,x:longint);
var mid:longint;
begin
inc(cnt); t[cnt]:=t[p];
p:=cnt; t[p].s:=t[p].s+x;
if l=r then exit;
mid:=(l+r)>>;
if v<=mid then update(l,mid,t[p].l,v,x)
else update(mid+,r,t[p].r,v,x);
end; function query(l,r,k:longint):longint;
var s1,s2,i,mid:longint;
begin
if l=r then exit(l);
s1:=; s2:=;
for i:= to la do s1:=s1+t[t[left[i]].l].s;
for i:= to lb do s2:=s2+t[t[right[i]].l].s;
mid:=(l+r)>>;
if s2-s1>=k then
begin
for i:= to la do left[i]:=t[left[i]].l;
for i:= to lb do right[i]:=t[right[i]].l;
exit(query(l,mid,k));
end
else
begin
for i:= to la do left[i]:=t[left[i]].r;
for i:= to lb do right[i]:=t[right[i]].r;
exit(query(mid+,r,k-(s2-s1)));
end;
end; begin
assign(input,'data.in'); reset(input);
assign(output,'bzoj1901.out'); rewrite(output);
readln(n,m);
q:=;
for i:= to n do
begin
read(a[i]);
inc(q); b[q]:=a[i];
end;
readln;
for i:= to m do
begin
readln(ch); s:=;
if ch[]='C' then
begin
inc(q);
for j:= to length(ch) do
begin
if ch[j]=' ' then begin inc(s); continue; end;
d[i,s+]:=d[i,s+]*+ord(ch[j])-ord('');
end;
b[q]:=d[i,];
end;
if ch[]='Q' then
begin
flag[i]:=;
for j:= to length(ch) do
begin
if ch[j]=' ' then begin inc(s); continue; end;
d[i,s+]:=d[i,s+]*+ord(ch[j])-ord('');
end;
end;
end;
qsort(,q);
hash[]:=b[]; u:=;
for i:= to q do
if b[i]<>b[i-] then begin inc(u); hash[u]:=b[i]; end; for i:= to n do
begin
tmp:=find(a[i]);
j:=i;
while j<=n do
begin
update(,u,root[j],tmp,);
j:=j+lowbit(j);
end;
end; for i:= to m do
if flag[i]= then
begin
la:=; lb:=; j:=d[i,]-;
while j> do
begin
inc(la); left[la]:=root[j];
j:=j-lowbit(j);
end;
j:=d[i,];
while j> do
begin
inc(lb); right[lb]:=root[j];
j:=j-lowbit(j);
end;
writeln(hash[query(,u,d[i,])]);
end
else
begin
tmp:=find(a[d[i,]]);
j:=d[i,];
while j<=n do
begin
update(,u,root[j],tmp,-);
j:=j+lowbit(j);
end;
tmp:=find(d[i,]);
j:=d[i,];
while j<=n do
begin
update(,u,root[j],tmp,);
j:=j+lowbit(j);
end;
a[d[i,]]:=d[i,];
end;
close(input);
close(output);
end.
UPD(2018.9.21):C++
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 3100000
#define M 30000
#define MOD 1000000007
#define eps 1e-8
#define pi acos(-1)
#define oo 1e9 char ch[];
struct arr
{
int l,r,s;
}t[N];
int a[M],b[M],root[M],
L[],R[],A[M],B[M],K[M],flag[M],
n,m,cnt,l1,l2,mx; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} int lowbit(int x)
{
return x&(-x);
} int lsh(int x)
{
int l=;
int r=mx;
while(l<=r)
{
int mid=(l+r)>>;
if(b[mid]==x) return mid;
if(b[mid]<x) l=mid+;
else r=mid-;
}
} void update(int l,int r,int x,int v,int &p)
{
t[++cnt].l=t[p].l;
t[cnt].r=t[p].r;
t[cnt].s=t[p].s;
p=cnt;
t[p].s+=v;
if(l==r) return;
int mid=(l+r)>>;
if(x<=mid) update(l,mid,x,v,t[p].l);
else update(mid+,r,x,v,t[p].r);
} int query(int l,int r,int k)
{
//printf("%d %d %d ",l,r,k);
if(l==r) return l;
int s1=;
int s2=;
for(int i=;i<=l1;i++) s1+=t[t[L[i]].l].s;
for(int i=;i<=l2;i++) s2+=t[t[R[i]].l].s;
int tmp=s2-s1;
//printf("%d\n",tmp);
int mid=(l+r)>>;
if(tmp>=k)
{
for(int i=;i<=l1;i++) L[i]=t[L[i]].l;
for(int i=;i<=l2;i++) R[i]=t[R[i]].l;
return query(l,mid,k);
}
else
{
for(int i=;i<=l1;i++) L[i]=t[L[i]].r;
for(int i=;i<=l2;i++) R[i]=t[R[i]].r;
return query(mid+,r,k-tmp);
}
} int main()
{
freopen("data.in","r",stdin);
freopen("bzoj1901.out","w",stdout);
int q;
scanf("%d%d",&n,&q);
m=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
b[++m]=a[i];
}
for(int i=;i<=q;i++)
{
scanf("%s",ch);
scanf("%d%d",&A[i],&B[i]);
if(ch[]=='Q'){scanf("%d",&K[i]); flag[i]=;}
else b[++m]=B[i];
}
sort(b+,b+m+);
cnt=;
mx=;
for(int i=;i<=m;i++)
if(b[i]!=b[mx]) b[++mx]=b[i];
for(int i=;i<=n;i++)
{
int tmp=lsh(a[i]);
int j=i;
while(j<=n)
{
update(,mx,tmp,,root[j]);
j+=lowbit(j);
}
} for(int i=;i<=q;i++)
if(flag[i])
{
l1=; l2=; A[i]--;
int j=A[i];
while(j)
{
L[++l1]=root[j];
j-=lowbit(j);
}
j=B[i];
while(j)
{
R[++l2]=root[j];
j-=lowbit(j);
}
printf("%d\n",b[query(,mx,K[i])]);
}
else
{
int x=lsh(a[A[i]]);
int j=A[i];
while(j<=n)
{
update(,mx,x,-,root[j]);
j+=lowbit(j);
}
a[A[i]]=B[i];
x=lsh(B[i]);
j=A[i];
while(j<=n)
{
update(,mx,x,,root[j]);
j+=lowbit(j);
}
} }
【BZOJ1901】Dynamic Rankings(树套树,树状数组,主席树)的更多相关文章
- BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树
BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...
- zoj2112 树状数组+主席树 区间动第k大
Dynamic Rankings Time Limit: 10000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Subm ...
- BZOJ_2120_数颜色_Set+树状数组+主席树
BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...
- 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...
- P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]
题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...
- [BZOJ 1146] [CTSC2008]网络管理Network(树状数组+主席树)
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】
题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...
- [BZOJ1901][luogu2617]Dynamic Rankings(树状数组+主席树)
题面 单点修改,区间求第k大 分析 首先,这道题卡权值线段树套treap的做法,所以只能用主席树做 对于静态的查询,root[i]对应的主席树的区间[l,r]保存的是a[1]~a[i]有多少个值落在区 ...
- ZOJ 2112 Dynamic Rankings(树状数组+主席树)
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
随机推荐
- Chunky Monkey-freecodecamp算法题目
Chunky Monkey(猴子吃香蕉, 分割数组) 要求 把一个数组arr按照指定的数组大小size分割成若干个数组块. 思路 利用size值和while语句确定切割数组的次数(定义temp将siz ...
- python入门:py2.x里面除法或乘法这么写就可以计算小数点后面结果
#!/usr/bin/env python # -*- coding:utf-8 -*- #py2.x里面除法或乘法这么写就可以计算小数点后面结果,更精确future(未来,译音:非忧车) divis ...
- Lecture 3
surface models 1. The two main methods of creating surface models are interpolation and triangulatio ...
- Python模块(三)(正则,re,模块与包)
1. 正则表达式 匹配字符串 元字符 . 除了换行 \w 数字, 字母, 下划线 \d 数字 \s 空白符 \n 换行符 \t 制表符 \b 单词的边界 \W \D \S 非xxx [ ...
- w3resource_MySQL练习:Subquery
w3resource_MySQL练习题:Subquery 1. Write a query to find the name (first_name, last_name) and the salar ...
- leetcode-27-exercise_bit maniputation
461. Hamming Distance 解题思路: 把两个数的每一位和1比较,如果结果不同说明这两位不同.要比较32次. int hammingDistance(int x, int y) { i ...
- Developing for nRF52810(转载)
Table of Contents Introduction Hardware emulation of nRF52810 Limitations Software emulation of nRF5 ...
- HDU 3594 Cactus 有向仙人掌图判定
题意 给出一个有向图,并给出仙人掌图的定义 图本身是强连通的 每条边属于且只属于一个环 判断输入的图是否是强连通的. 分析 杭电OJ上的数据比较弱,网上一些有明显错误的代码也能AC. 本着求真务实的精 ...
- day05 模块以及内置常用模块用法
内置常用模块详解: 1 time 2 datetime 3 random 4 os 5 sys 6 shutil 7 shelve 8 xml 9 configparser 10 hashlib ...
- Linux性能查看
1.TOP top 登录后默认按进程的CPU使用情况排序, 按M则按内存使用排序 2. vmstat 2 2 显示系统负载 3. free -m 查看内存使用情况 4.抓包 tcpdump -i ...