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). 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 题意:询问区间第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]); } }
作者:xxy