Problem Description
There are N boys in CodeLand.
Boy i has his coding skill Ai.
CRB wants to know who has the suitable coding skill.
So you should treat the following two types of queries.
Query 1: 1 l v
The coding skill of Boy l has changed to v.
Query 2: 2 l r k
This is a report query which asks the k-th smallest value of coding skill between Boy l and Boy r(both inclusive).
Input
There are multiple test cases.
The first line contains a single integer N.
Next line contains N space separated integers A1, A2, …, AN, where Ai denotes initial coding skill of Boy i.
Next line contains a single integer Q representing the number of queries.
Next Q lines contain queries which can be any of the two types.
1 ≤ N, Q ≤ 105
1 ≤ Ai, v ≤ 109
1 ≤ l ≤ r ≤ N
1 ≤ k ≤ r – l + 1
 
Output
For each query of type 2, output a single integer corresponding to the answer in a single line.
 
Sample Input
5
1 2 3 4 5
3
2 2 4 2
1 3 6
2 2 4 2
Sample Output
3 4
 
题解:
按时间顺序加入,所有的修改拆成删除和添加两个操作,分别对应树状数组中的加减.
维护时间顺序即可
 #include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int N=;
int gi(){
int str=;char ch=getchar();
while(ch>'' || ch<'')ch=getchar();
while(ch>='' && ch<='')str=(str<<)+(str<<)+ch-,ch=getchar();
return str;
}
int n,m,a[N],top=,ans[N];
struct node{
int x,y,cnt,k,id;
}t[N*],q1[N*],q2[N*];
int Tree[N*];
void add(int sta,int ad){
for(int i=sta;i<=n;i+=(i&(-i)))Tree[i]+=ad;
}
int getsum(int sta){
int sum=;
for(int i=sta;i>=;i-=(i&(-i)))sum+=Tree[i];
return sum;
}
int l1=,l2=;
void count(int ll,int rr,int dl,int dr)
{
for(int i=ll;i<=rr;i++)
{
if(t[i].k)
t[i].cnt=getsum(t[i].y)-getsum(t[i].x-);
else if(t[i].y<=dr)
add(t[i].x,t[i].cnt);
}
for(int i=ll;i<=rr;i++)
if(!t[i].k && t[i].y<=dr)
add(t[i].x,-t[i].cnt);
l1=;l2=;
for(int i=ll;i<=rr;i++)
{
if(t[i].k)
{
if(t[i].cnt>=t[i].k)
q1[++l1]=t[i];
else
t[i].k-=t[i].cnt,q2[++l2]=t[i];
}
else
{
if(t[i].y<=dr)
q1[++l1]=t[i];
else
q2[++l2]=t[i];
}
}
int now=ll-;
for(int i=;i<=l1;i++)
t[++now]=q1[i];
for(int i=;i<=l2;i++)
t[++now]=q2[i];
}
void div(int ll,int rr,int dl,int dr)
{
if(dl==dr)
{
for(int i=ll;i<=rr;i++)
if(t[i].k)ans[t[i].id]=dl;
return ;
}
int mid=(dl+dr)>>;
count(ll,rr,dl,mid);
int to=l1;
if(to)
div(ll,ll+to-,dl,mid);
if(to<=rr-ll)
div(ll+to,rr,mid+,dr);
}
void Clear(){
top=;
memset(ans,,sizeof(ans));
memset(t,,sizeof(t));
}
void work()
{
Clear();
for(int i=;i<=n;i++)
{
a[i]=gi();
t[++top]=((node){i,a[i],,,});
}
m=gi();
int flag,x,y,z;
for(int i=;i<=m;i++)
{
flag=gi();
if(flag==)
{
x=gi();y=gi();
t[++top]=((node){x,a[x],-,,});
t[++top]=((node){x,y,,,});
a[x]=y;
}
else
{
x=gi();y=gi();z=gi();
t[++top]=(node){x,y,,z,i};
}
}
div(,top,,1e9);
for(int i=;i<=m;i++)if(ans[i])printf("%d\n",ans[i]);
}
int main()
{
while(~scanf("%d",&n))
work();
return ;
}

还有主席树维护的树状数组,但是MLE,这种题目如果数据小可以用

 #include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int N=;
int n,m,a[N],b[N<<];
struct Ques{
int flag,x,y,k;
}q[N];
int num=,bel[N];
int getrank(int x){
int l=,r=num,mid;
while(l<=r)
{
mid=(l+r)>>;
if(b[mid]==x)return mid;
if(x>b[mid])l=mid+;
else r=mid-;
}
}
struct Tree{
int ls,rs,cnt;
}t[N*];
int root[N],tot=;
void add(int &rt,int l,int r,int val,int ad)
{
t[++tot]=t[rt];rt=tot;t[rt].cnt+=ad;
if(l==r)return ;
int mid=(l+r)>>;
if(val<=mid)add(t[rt].ls,l,mid,val,ad);
else add(t[rt].rs,mid+,r,val,ad);
}
void updata(int sta,int val,int ad)
{
for(int i=sta;i<=n;i+=(i&(-i)))add(root[i],,num,val,ad);
}
int nl[N],nr[N];
int query(int ll,int rr,int rank)
{
int l=,r=num,mid;
int lenl=,lenr=,sl,sr;
for(int i=ll;i>=;i-=(i&(-i)))nl[++lenl]=root[i];
for(int i=rr;i>=;i-=(i&(-i)))nr[++lenr]=root[i];
while(l<r)
{
mid=(l+r)>>;
sl=sr=;
for(int i=;i<=lenl;i++)sl+=t[t[nl[i]].ls].cnt;
for(int i=;i<=lenr;i++)sr+=t[t[nr[i]].ls].cnt;
if(sr-sl>=rank)
{
for(int i=;i<=lenl;i++)nl[i]=t[nl[i]].ls;
for(int i=;i<=lenr;i++)nr[i]=t[nr[i]].ls;
r=mid;
}
else
{
for(int i=;i<=lenl;i++)nl[i]=t[nl[i]].rs;
for(int i=;i<=lenr;i++)nr[i]=t[nr[i]].rs;
l=mid+;rank-=sr-sl;
}
}
return b[r];
}
void Clear()
{
tot=;num=;
memset(root,,sizeof(root));
memset(t,,sizeof(t));
}
void work()
{
Clear();
for(int i=;i<=n;i++)scanf("%d",&a[i]),b[++num]=a[i];
scanf("%d",&m);
for(int i=;i<=m;i++)
{
scanf("%d",&q[i].flag);
if(q[i].flag==){
scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].k);
}
else{
scanf("%d%d",&q[i].x,&q[i].y);
b[++num]=q[i].y;
}
}
sort(b+,b+num+);
for(int i=;i<=n;i++)bel[i]=getrank(a[i]);
for(int i=;i<=n;i++)updata(i,bel[i],);
for(int i=;i<=m;i++)
{
if(q[i].flag==)
{
updata(q[i].x,bel[q[i].x],-);
updata(q[i].x,q[i].y=getrank(q[i].y),);
bel[q[i].x]=q[i].y;
}
else
printf("%d\n",query(q[i].x-,q[i].y,q[i].k));
}
}
int main()
{
//freopen("pp.in","r",stdin);
//freopen("pp.out","w",stdout);
while(~scanf("%d",&n))
work();
return ;
}

HDU 5412 CRB and Queries 动态整体二分的更多相关文章

  1. hdu 5412 CRB and Queries

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5412 CRB and Queries Description There are $N$ boys i ...

  2. HDU - 5412 CRB and Queries (整体二分)

    题目链接 动态区间第k小,但是这道题的话用主席树+树状数组套线段树的空间复杂度是O(nlog2n)会爆掉. 另一种替代的方法是用树状数组套平衡树,空间复杂度降到了O(nlogn),但我感觉平衡树是个挺 ...

  3. hdu 5412 CRB and Queries(整体二分)

    题意 动态区间第k大 (n<=100000,m<=100000) 题解 整体二分的应用. 与静态相比差别不是很大.(和CDQ还有点像)所以直接上代码. #include<iostre ...

  4. HDU 5412——CRB and Queries——————【线段树套Treap(并没有AC)】

    CRB and Queries Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  5. 2015 Multi-University Training Contest 10 hdu 5412 CRB and Queries

    CRB and Queries Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  6. HDU 5412 CRB and Queries(区间第K大 树套树 按值建树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5412 Problem Description There are N boys in CodeLan ...

  7. Hdu CRB and Queries(整体二分)

    CRB and Queries Time Limit: 6000 MS Memory Limit: 131072 K Problem Description There are N boys in C ...

  8. HDU5412 CRB and Queries 整体二分

    传送门 刚觉得最近写代码比较顺畅没什么Bug,cdq分治真是我的一个噩梦.. 整体二分模板题,带修改的区间第k小. vjudge不知抽什么风,用不了,hdu忘了密码了一直在那里各种试,难受.. 写得比 ...

  9. ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112 题意: 求动态区间第K大. 分析: 把修改操作看成删除与增加 ...

随机推荐

  1. 201621123043 《Java程序设计》第3周学习总结

    1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识点组织起来.请使用工具画出本周学习到的知识点及知识点之间的联系.步骤如下: 1.1 写出你 ...

  2. 浏览器关闭后,Session会话结束了么?

    今天想和大家分享一个关于Session的话题: 当浏览器关闭时,Session就被销毁了? 我们知道Session是JSP的九大内置对象(也叫隐含对象)中的一个,它的作用是可以保 存当前用户的状态信息 ...

  3. Jmeter读取文件中的值《一》

    此篇主要是对应上一章节的呼应,上一篇中讲到将返回值写入文件,这个值如果在下一个接口中用到, 那么我们需要去从文件中读取数据,这是我们该如何操作? 一.测试计划中添加CSV Data Set Confi ...

  4. linux 下 nc 命令的使用

    netcat被誉为网络安全界的'瑞士军刀',一个简单而有用的工具,透过使用TCP或UDP协议的网络连接去读写数据.它被设计成一个稳定的后门工具,能够直接由其它程序和脚本轻松驱动.同时,它也是一个功能强 ...

  5. centos 6.5安装并配置mysql

    折腾了半天终于把mysql安装并配置好了,以下是安装步骤和遇到问题的解决方式 1.查看机器上是否已经安装了mysql或其相关项 # yum list installed | grep mysql如果安 ...

  6. Hadoop完全分布式安装教程

    一.软件版本 Hadoop版本号:hadoop-2.6.0.tar: VMWare版本号:VMware-workstation-full-11.0.0-2305329 Ubuntu版本号:ubuntu ...

  7. [八省联考2018] 劈配 mentor

    Description 一年一度的综艺节目<中国新代码>又开始了.Zayid 从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. Input 轻车熟路的Zay ...

  8. copy代码(含static对象)留下的致命错误

    本来以为这个bug快改不好了,然而发现了问题所在 copy代码没有完全改掉对象名称,导致对象重复创建了,由于是static所以debug过程中 注释了addProperty(gridRowDetail ...

  9. R语言学习 第九篇:plyr包

    在数据分析中,整理数据的本质可以归纳为:对数据进行分割(Split),然后应用(Apply)某些处理函数,最后将结果重新组合(Combine)成所需的格式返回,简单描述为:Split - Apply ...

  10. 【Java】0X003 面向对象

    一. 什么是面向对象 都说Java是一门面向对象的语言,但什么对象?什么又是面向对象?以下都是我学到的知识和一点自己的理解. 对象是指包含属性和行为的主体. 比如,人有性别.血型.单眼皮或双眼皮等的特 ...