901: Zju2112 Dynamic Rankings

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 7025  Solved: 2925
[Submit][Status][Discuss]

Description

给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。 第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。

Input

对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

Output

 

Sample Input

5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3

Sample Output

3
6

HINT

20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。

-------------------------------------------------------------------------------------

嗷嗷嗷A了好海森

首先要回忆一下树状数组的样子。。它是一棵树的结构,也就是一个点只会被另一个点所访问到(父亲只有一个)。

上一题不带修改的主席树中,每一棵树是维护前缀区间1~L的。

这样,要是我们要修改一个数的话,就要把后面的主席树全部修改了。。复杂度变成了m*n*logn,这是不能接受的。

然后大神们就想到了树状数组!

我们修改每一棵主席树维护的区间,对于第i棵主席树,维护树状数组中所对应的lowbit(i)个数。

然后修改就只需要m*logn*logn了。

查询则变成了logn*logn的了。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std; const int N=,INF=(int)1e9+;
int n,m,pl,tl,mx;
int a[*N],num[*N],crt[*N],root[*N];
char s[];
struct trnode{
int lc,rc,cnt;
}t[*N];
struct ques{
int l,r,k,x,d;
bool tmp;
}q[N];
struct node{
int d,id;
}p[*N]; bool cmp(node x,node y){return x.d<y.d;} int bt(int l,int r)
{
int x=++tl;
t[x].cnt=;
t[x].lc=t[x].rc=;
if(l<r)
{
int mid=(l+r)/;
t[x].lc=bt(l,mid);
t[x].rc=bt(mid+,r);
}
return x;
} int update(int rt,int p,int d)
{
int now=++tl,tmp=now;
int l=,r=mx,mid;
t[now].cnt=t[rt].cnt+d;
while(l<r)
{
mid=(l+r)/;
if(p<=mid)
{
r=mid;
t[now].lc=++tl;
t[now].rc=t[rt].rc;
rt=t[rt].lc;
now=tl;
}
else
{
l=mid+;
t[now].lc=t[rt].lc;
t[now].rc=++tl;
rt=t[rt].rc;
now=tl;
}
t[now].cnt=t[rt].cnt+d;
}
return tmp;
} void add(int x,int p,int d)
{
for(int i=x;i<=n;i+=(i&(-i))) root[i]=update(root[i],p,d);
} int getsum(int x)
{
int ans=;
for(int i=x;i>=;i-=(i&(-i))) ans+=t[t[crt[i]].lc].cnt;
return ans;
} int query(int lx,int rx,int k)
{
for(int i=lx-;i>=;i-=(i&(-i))) crt[i]=root[i];//多棵树同时走。
for(int i=rx;i>=;i-=(i&(-i))) crt[i]=root[i];
int l=,r=mx,mid,sum;
while(l<r)
{
mid=(l+r)/;
sum=getsum(rx)-getsum(lx-);
if(sum>=k)
{
r=mid;
for(int i=lx-;i>=;i-=(i&(-i))) crt[i]=t[crt[i]].lc;
for(int i=rx;i>=;i-=(i&(-i))) crt[i]=t[crt[i]].lc;
}
else
{
l=mid+;
k-=sum;
for(int i=lx-;i>=;i-=(i&(-i))) crt[i]=t[crt[i]].rc;
for(int i=rx;i>=;i-=(i&(-i))) crt[i]=t[crt[i]].rc;
}
}
return l;
} int main()
{
freopen("a.in","r",stdin);
scanf("%d%d",&n,&m);
pl=n;tl=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
p[i].d=a[i];p[i].id=i;
}
for(int i=;i<=m;i++)
{
scanf("%s",s);
if(s[]=='Q')
{
q[i].tmp=;
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
}
else
{
q[i].tmp=;
scanf("%d%d",&q[i].x,&q[i].d);
p[++pl].d=q[i].d;p[pl].id=n+i;
}
}
sort(p+,p++pl,cmp);
mx=;p[].d=INF;
for(int i=;i<=pl;i++)
{
if(p[i].d!=p[i-].d) mx++,num[mx]=p[i].d;
if(p[i].id<=n) a[p[i].id]=mx;
else q[p[i].id-n].d=mx;
}
// for(int i=1;i<=n;i++) printf("%d ",a[i]);printf("\n");
root[]=bt(,mx);
for(int i=;i<=n;i++)
root[i]=root[];
for(int i=;i<=n;i++)
add(i,a[i],);
for(int i=;i<=m;i++)
{
if(q[i].tmp==)
printf("%d\n",num[query(q[i].l,q[i].r,q[i].k)]);
else
{
add(q[i].x,a[q[i].x],-);
add(q[i].x,q[i].d,);
a[q[i].x]=q[i].d;//debug
}
}
return ;
}

【poj1901-求区间第k大值(带修改)】树状数组套主席树的更多相关文章

  1. ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解

    题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...

  2. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  3. Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)

    E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...

  4. 【树状数组套主席树】带修改区间K大数

    P2617 Dynamic Rankings 题目描述给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+ ...

  5. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  6. 【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题

    达神题解传送门:http://blog.csdn.net/dad3zz/article/details/50638360 说一下我对这个模板的理解: 看到这个方法很容易不知所措,因为动态K值需要套树状 ...

  7. ZOJ 2112 Dynamic Rankings (动态第k大,树状数组套主席树)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

  8. 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))

    函数式线段树..资瓷 区间第K极值查询 似乎不过似乎划分树的效率更优于它,但是如果主席树套树状数组后,可以处理动态的第K极值.即资瓷插入删除,划分树则不同- 那么原理也比较易懂: 建造一棵线段树(权值 ...

  9. ZOJ 2112 Dynamic Rankings (动态第 K 大)(树状数组套主席树)

    Dynamic Rankings Time Limit: 10 Seconds      Memory Limit: 32768 KB The Company Dynamic Rankings has ...

随机推荐

  1. Linux上安装MySQL - 12条命令搞定MySql

    从零开始安装mysql数据库 : 按照该顺序执行 :  a. 查看是否安装有mysql:yum list installed mysql*, 如果有先卸载掉, 然后在进行安装; b. 安装mysql客 ...

  2. Java微笔记(3)

    Java 中的 static 使用之静态变量 Java 中被 static 修饰的成员称为静态成员或类成员. 它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享. 静态成员可以使用类名直接访 ...

  3. 3DMAX2016安装教程【图文】

    下载安装包之后,双击setup.exe. 下面是安装图片教程: 点击安装 点击下一步. 如图输入序列号和产品密钥. 填写安装路径,然后下一步. 开始安装,等待. 安装成功.

  4. PagedDataSource数据绑定控件和AspNetPager分页控件结合使用列表分页

    1.引用AspNetPager.dll. 2.放置Repeater数据绑定控件. <asp:Repeater ID="Repeater1" runat="serve ...

  5. 【APS.NET Core】- Json配置文件的读取

    在项目目录下有个 appsettings.json ,我们先来操作这个文件.在appsettings.json中添加以下内容: { "Logging": { "LogLe ...

  6. Tomcat启动报错ERROR:transport error 202:bind failed:Address already

    昨天在服务器上拷贝了一个tomcat项目,修改了server.xml之后启动居然报错ERROR:transport error 202:bind failed:Address already,应该是远 ...

  7. 【python】Python 之 __new__() 方法与实例化

    本文转自:http://www.cnblogs.com/ifantastic/p/3175735.html __new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 ...

  8. 在ios 上 按钮 disabled 样式显示异常

    将input,button或textarea设置为disabled后,在iphone手机上样式将被覆写-webkit-appearance:none; 文字的颜色还是灰色. 原本在android 上 ...

  9. java 中使用Base64

    byte[] cipherData = Base64.encodeBase64(plainText.getBytes()); //默认不换行 byte[] cipherData = Base64.en ...

  10. 【bzoj1609】[Usaco2008 Feb]Eating Together麻烦的聚餐 dp

    题目描述 为了避免餐厅过分拥挤,FJ要求奶牛们分3批就餐.每天晚饭前,奶牛们都会在餐厅前排队入内,按FJ的设想所有第3批就餐的奶牛排在队尾,队伍的前端由设定为第1批就餐的奶牛占据,中间的位置就归第2批 ...