题意:给定一个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. iOS重绘机制drawRect

    iOS的绘图操作是在UIView类的drawRect方法中完成的,所以如果我们要想在一个UIView中绘图,需要写一个扩展UIView 的类,并重写drawRect方法,在这里进行绘图操作,程序会自动 ...

  2. linux关于任务计划

    1.一次性任务计划:at 1)添加 在18:16时候重启服务器 at 18:16 >at init 6 >at ctrl+d2)查看 atq 1 Mon Aug 20 21:09:00 2 ...

  3. html5音频audio对象处理以及ios微信端自动播放和息屏后唤醒的判断---可供参考(功能都完整实现了,只是细节还没处理的很好)

    // html模版中的 此处结合了weui样式整合的微信手机端片段代码(不可直接粘贴复制进行使用)里面含有一些php的写法,可直接略过..###重点参考js代码### <div> < ...

  4. yield关键字有什么作用

    所属网站分类: python基础 > 语句 作者:goodbody 链接: http://www.pythonheidong.com/blog/article/10/ 来源:python黑洞网  ...

  5. python-闭包函数和装饰器

    目录 闭包函数 什么是闭包? 两种为函数传参的方式 使用参数的形式 包给函数 闭包函数的应用 闭包的意义: 装饰器 无参装饰器 什么是装饰器 为什么要用装饰器 怎么用装饰器 完善装饰器 闭包函数 什么 ...

  6. perl-basic-数据类型&引用

    我觉得这一系列的标题应该是:PERL,从入门到放弃 USE IT OR U WILL LOSE IT 参考资料: https://qntm.org/files/perl/perl.html 在线per ...

  7. for_each_node(node)

    遍历各个pg_data_t节点. 1.定义在include/linux/nodemask.h中 /* * Bitmasks that are kept for all the nodes. */ en ...

  8. LeetCode(307) Range Sum Query - Mutable

    题目 Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclus ...

  9. golang json 示例

    jsonStr, err := client.Get( deviceIdKey ).Result() if err == redis.Nil { deviceIds = []string{device ...

  10. linux中的部分宏

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...