题意:给定一个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. 类库日期和jsp导包

    一.日期类库 1.1. Date Date类创建一个时间,或者是创建一个与你计算机当前的时间:精确到毫秒. //实例化时间类 Date date = new Date(); 1.2.格式转换类 1.2 ...

  2. ajax $.post 一直报 Forbidden (CSRF token missing or incorrect.)

    由于后台整合类视图代码,所以修改了写法,完了之后用下面的写法写的post请求都报 403 error $.post( "{% url 'test_record:select_node_pag ...

  3. 【MySql】Mysql ERROR 1067: Invalid default value for ‘date’ 解决

    在给一个表添加字段的时候,忽然发现会报一个date类型的字段的默认值错误,郁闷~ 经过排查,原来是MySQL的配置问题,在wamp下,MySQL 5.7里是没有设置 SQL_MODE 的. 1.my. ...

  4. tmp_获取下一个回文数

    直接拿之前一次竞赛中写的code,稍微完善了点,后面有机会在优化 uint64_t GetNextPalindrome(uint64_t data) { //100以内的数字已经特殊考虑过,不存在差值 ...

  5. Python分布式爬虫开发搜索引擎 Scrapy实战视频教程

    点击了解更多Python课程>>> Python分布式爬虫开发搜索引擎 Scrapy实战视频教程 课程目录 |--第01集 教程推介 98.23MB |--第02集 windows下 ...

  6. 第二课:PHP 安装

    PHP 安装 您需要做什么? 为了开始使用 PHP,您可以: 找一个支持 PHP 和 MySQL 的 Web 主机 在您自己的 PC 机上安装 Web 服务器,然后安装 PHP 和 MySQL 使用支 ...

  7. Python基础-面向对象初识--类

    什么是类 具有相似功能和属性的一类实物 什么是对象 类的具体体现,具体到一个 面向对象的优势 1.类是一组相似功能的集合,使组织结构更加清晰和规范化 2.研究面向对象要有上帝的思维,用面向对象设计程序 ...

  8. 二叉苹果树——树形Dp(由根到左右子树的转移)

    题意:给出一个二叉树,每条边上有一定的边权,并且剪掉一些树枝,求留下 Q 条树枝的最大边权和. ( 节点数 n ≤100,留下的枝条树 Q ≤ n ,所有边权和 ∑w[i] ≤30000 ) 细节:对 ...

  9. JQuery根据字母检索元素并导航到指定位置

    介绍:类似于实现ios通讯录中右侧字母,快速导航到联系人的效果,如图: Html代码如下,分别是字母和港星名字的排序: <input type="text" id=" ...

  10. 关于freetype在安装中的遇到的问题

    本人电脑配置的是Anconda环境+pycharm2017.2.2 comuniity,每次安装什么包就是直接pip install 的,但是这次在安装freetype的安装中却遇到了麻烦. 具体是在 ...