题意:给定一个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(树套树,树状数组,主席树)的更多相关文章

  1. BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树

    BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...

  2. zoj2112 树状数组+主席树 区间动第k大

    Dynamic Rankings Time Limit: 10000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Subm ...

  3. BZOJ_2120_数颜色_Set+树状数组+主席树

    BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...

  4. 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  5. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  6. P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]

    题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...

  7. [BZOJ 1146] [CTSC2008]网络管理Network(树状数组+主席树)

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  8. [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】

    题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...

  9. [BZOJ1901][luogu2617]Dynamic Rankings(树状数组+主席树)

    题面 单点修改,区间求第k大 分析 首先,这道题卡权值线段树套treap的做法,所以只能用主席树做 对于静态的查询,root[i]对应的主席树的区间[l,r]保存的是a[1]~a[i]有多少个值落在区 ...

  10. ZOJ 2112 Dynamic Rankings(树状数组+主席树)

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

随机推荐

  1. js中替换字符串

    function formatStr(str){ str=str.replace(/\r\n/ig,"<br/>"); return str; } 要注意两点: 要使用 ...

  2. MySQL 5.7.20绿色版安装详细图文教程

    MySQL 5.7.20绿色版安装详细图文教程 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle旗下产品.这篇文章主要介绍了MySQL 5.7.20绿色版安装 ...

  3. 使用jsp读取某个目录下的所有文件名,并保存在json文件中

    <%@page import="java.io.File"%> <%@page import="java.io.FileWriter"%> ...

  4. bash编程之循环控制:

    bash编程之循环控制: for varName in LIST; do 循环体 done   while CONDITION; do 循环体 done   until CONDITION; do 循 ...

  5. cephfs 挂载 卸载

    #挂载 sudo ceph-fuse -m 10.1.xx.231:6789,10.1.xx.232:6789,10.1.xx.233:6789 -r /MySQL-BK /data/backup # ...

  6. PHP计算今天、昨天、本周、本月、上月开始时间和结束时间

    PHP计算今天.昨天.本周.本月.上月开始时间和结束时间 $today = date('Y-m-d H:i:s',mktime(0,0,0,date('m'),date('d'),date('Y')) ...

  7. 安装repo

    $ sudo apt-get install curl -y$ curl "http://android.git.linaro.org/gitweb?p=tools/repo.git;a=b ...

  8. Spring Boot + Mybatis 多数据源配置实现读写分离

    本文来自网易云社区 作者:王超 应用场景:项目中有一些报表统计与查询功能,对数据实时性要求不高,因此考虑对报表的统计与查询去操作slave db,减少对master的压力. 根据网上多份资料测试发现总 ...

  9. Xampp 配置出现403无法访问

    找到\xampp\apache\conf\httpd.conf配置文件 Access forbidden! You don’t have permission to access the reques ...

  10. [POJ 1008] Maya Calendar C++解题

        Maya Calendar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 62297   Accepted: 192 ...