您的位置:首页 > 产品设计 > UI/UE

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

2015-08-21 18:00 453 查看

CRB and Queries

Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 533 Accepted Submission(s): 125


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

Author
KUT(DPRK)

[align=left]Source[/align]
2015 Multi-University Training Contest 10 1007
解题:带修改的区间K大查询

#include <bits/stdc++.h>
using namespace std;
const int maxn = 300010;
const int INF = 0x3f3f3f3f;
struct QU {
int x,y,k,id,d;
} Q[maxn],A[maxn],B[maxn];
int a[maxn],c[maxn],ans[maxn],tot;
void add(int i,int val) {
while(i < maxn) {
c[i] += val;
i += i&-i;
}
}
int sum(int i,int ret = 0) {
while(i > 0) {
ret += c[i];
i -= i&-i;
}
return ret;
}
void solve(int lt,int rt,int L,int R) {
if(lt > rt) return;
if(L == R) {
for(int i = lt; i <= rt; ++i)
if(Q[i].id) ans[Q[i].id] = L;
return;
}
int mid = (L + R)>>1,a = 0,b = 0;
for(int i = lt; i <= rt; ++i) {
if(Q[i].id) {
int tmp = sum(Q[i].y) - sum(Q[i].x-1);
if(Q[i].d + tmp >= Q[i].k) A[a++] = Q[i];
else {
Q[i].d += tmp;
B[b++] = Q[i];
}
} else if(Q[i].y <= mid) {
add(Q[i].x,Q[i].d);
A[a++] = Q[i];
} else B[b++] = Q[i];
}
for(int i = lt; i <= rt; ++i)
if(!Q[i].id && Q[i].y <= mid) add(Q[i].x,-Q[i].d);
for(int i = 0; i < a; ++i) Q[lt + i] = A[i];
for(int i = 0; i < b; ++i) Q[lt + a + i] = B[i];
solve(lt,lt + a - 1,L,mid);
solve(lt + a,rt,mid + 1,R);
}
int main() {
int n,m,cnt,x,y;
while(~scanf("%d",&n)) {
memset(c,0,sizeof c);
cnt = tot = 0;
for(int i = 1; i <= n; ++i) {
scanf("%d",a + i);
Q[++tot].y = a[i];
Q[tot].x = i;
Q[tot].id = 0;
Q[tot].d = 1;
}
scanf("%d",&m);
for(int i = 1,op; i <= m; ++i) {
scanf("%d",&op);
if(op == 2) {
tot++;
scanf("%d%d%d",&Q[tot].x,&Q[tot].y,&Q[tot].k);
Q[tot].id = ++cnt;
Q[tot].d = 0;
} else {
scanf("%d%d",&x,&y);
Q[++tot].x = x;
Q[tot].y = a[x];
Q[tot].id = 0;
Q[tot].d = -1;

Q[++tot].x = x;
Q[tot].y = a[x] = y;
Q[tot].id = 0;
Q[tot].d = 1;
}
}
solve(1,tot,0,INF);
for(int i = 1; i <= cnt; ++i)
printf("%d\n",ans[i]);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: