CRB and Queries
http://acm.hdu.edu.cn/showproblem.php?pid=5412
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
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).
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
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
题意:询问区间第k值(小),支持修改操作
整体二分+树状数组
本题与上题不同处在于这里要多组数据输入
#include<cstdio>
#include<cstring>
using namespace std;
#define N 100001
int n,m,tot,t;
int ans[N*2],a[N],k[N*3];
int c[N];
struct node
{
int posx,posy,key,kind,bl,cur;
}q[N*3],tmp1[N*3],tmp2[N*3];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int y)
{
while(x<=n)
{
c[x]+=y;
x+=lowbit(x);
}
}
int sum(int x)
{
int b=0;
while(x)
{
b+=c[x];
x-=lowbit(x);
}
return b;
}
void solve(int head,int tail,int l,int r)
{
if(head>tail) return;
if(l==r)
{
for(int i=head;i<=tail;i++)
if(q[i].kind==3) ans[q[i].bl]=l;
return;
}
int mid=l+r>>1;
for(int i=head;i<=tail;i++)
{
if(q[i].kind==1&&q[i].key<=mid) add(q[i].posx,-1);
else if(q[i].kind==2&&q[i].key<=mid) add(q[i].posx,1);
else if(q[i].kind==3) k[i]=sum(q[i].posy)-sum(q[i].posx-1);
}
for(int i=head;i<=tail;i++)
{
if(q[i].kind==1&&q[i].key<=mid) add(q[i].posx,1);
else if(q[i].kind==2&&q[i].key<=mid) add(q[i].posx,-1);
}
int ll=0,rr=0;
for(int i=head;i<=tail;i++)
{
if(q[i].kind==3)
{
if(q[i].cur+k[i]>=q[i].key) tmp1[++ll]=q[i];
else
{
q[i].cur+=k[i];
tmp2[++rr]=q[i];
}
}
else
{
if(q[i].key<=mid) tmp1[++ll]=q[i];
else tmp2[++rr]=q[i];
}
}
for(int i=1;i<=ll;i++) q[head+i-1]=tmp1[i];
for(int i=1;i<=rr;i++) q[head+ll+i-1]=tmp2[i];
solve(head,head+ll-1,l,mid);solve(head+ll,tail,mid+1,r);
}
void pre()
{
tot=t=0;
memset(c,0,sizeof(c));
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
pre();
int x,y,z;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
q[++tot]=(node){i,0,x,2};
a[i]=x;
}
scanf("%d",&m);
int h;
for(int i=1;i<=m;i++)
{
scanf("%d",&h);
if(h==2)
{
scanf("%d%d%d",&x,&y,&z);
q[++tot]=(node){x,y,z,3,++t,0};
}
else
{
scanf("%d%d",&x,&z);
q[++tot]=(node){x,0,a[x],1,0,0};
q[++tot]=(node){x,0,z,2,0,0};
a[x]=z;
}
}
solve(1,tot,0,1e9);
for(int i=1;i<=t;i++) printf("%d\n",ans[i]);
}
}