题意:给定一个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. Chunky Monkey-freecodecamp算法题目

    Chunky Monkey(猴子吃香蕉, 分割数组) 要求 把一个数组arr按照指定的数组大小size分割成若干个数组块. 思路 利用size值和while语句确定切割数组的次数(定义temp将siz ...

  2. python入门:py2.x里面除法或乘法这么写就可以计算小数点后面结果

    #!/usr/bin/env python # -*- coding:utf-8 -*- #py2.x里面除法或乘法这么写就可以计算小数点后面结果,更精确future(未来,译音:非忧车) divis ...

  3. Lecture 3

    surface models 1. The two main methods of creating surface models are interpolation and triangulatio ...

  4. Python模块(三)(正则,re,模块与包)

    1. 正则表达式 匹配字符串 元字符 .   除了换行 \w  数字, 字母, 下划线 \d  数字 \s  空白符 \n 换行符 \t  制表符 \b  单词的边界 \W  \D \S 非xxx [ ...

  5. w3resource_MySQL练习:Subquery

    w3resource_MySQL练习题:Subquery 1. Write a query to find the name (first_name, last_name) and the salar ...

  6. leetcode-27-exercise_bit maniputation

    461. Hamming Distance 解题思路: 把两个数的每一位和1比较,如果结果不同说明这两位不同.要比较32次. int hammingDistance(int x, int y) { i ...

  7. Developing for nRF52810(转载)

    Table of Contents Introduction Hardware emulation of nRF52810 Limitations Software emulation of nRF5 ...

  8. HDU 3594 Cactus 有向仙人掌图判定

    题意 给出一个有向图,并给出仙人掌图的定义 图本身是强连通的 每条边属于且只属于一个环 判断输入的图是否是强连通的. 分析 杭电OJ上的数据比较弱,网上一些有明显错误的代码也能AC. 本着求真务实的精 ...

  9. day05 模块以及内置常用模块用法

    内置常用模块详解: 1 time 2 datetime 3 random   4 os 5 sys 6 shutil 7 shelve 8 xml 9 configparser 10 hashlib ...

  10. Linux性能查看

    1.TOP top  登录后默认按进程的CPU使用情况排序,  按M则按内存使用排序 2. vmstat 2 2 显示系统负载 3. free  -m 查看内存使用情况 4.抓包 tcpdump -i ...