标签:des style http color java os io strong
解题报告
题意:
意思很好理解。
思路:
每次操作是100000次,数据大小100000,又是多组输入。普通模拟肯定不行。
线段树结点记录区间里存在数字的个数,加点删点操作就让该点个数+1,判断x存在就查询[1,x]区间的个数和[1,x-1]的个数。
求x之后第k大的数就先确定小于x的个数t,第t+k小的数就是要求的。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int sum[1000000],ans;
void push_up(int rt) {
sum[rt]=sum[rt*2]+sum[rt*2+1];
}
void update(int rt,int l,int r,int p,int v) {
if(l==r) {
sum[rt]+=v;
return;
}
int mid=(l+r)/2;
if(p<=mid)
update(rt*2,l,mid,p,v);
else update(rt*2+1,mid+1,r,p,v);
push_up(rt);
}
int q_sum(int rt,int l,int r,int ql,int qr) {
if(ql>r||qr<l)return 0;
if(ql<=l&&r<=qr)
return sum[rt];
int mid=(l+r)/2;
return q_sum(rt*2,l,mid,ql,qr)+q_sum(rt*2+1,mid+1,r,ql,qr);
}
void find_rt(int rt,int l,int r,int t) {
int mid=(l+r)/2;
if(t>sum[rt*2]) {
if(l==r) {
ans=r;
return ;
}
find_rt(rt*2+1,mid+1,r,t-sum[rt*2]);
} else find_rt(rt*2,l,mid,t);
}
int main() {
int n,m,i,j,p,e,k;
while(~scanf("%d",&m)) {
n=100000;
memset(sum,0,sizeof(sum));
for(i=0; i<m; i++) {
scanf("%d",&p);
if(p==0) {
scanf("%d",&e);
update(1,1,n,e,1);
} else if(p==1) {
scanf("%d",&e);
if(q_sum(1,1,n,1,e)==q_sum(1,1,n,1,e-1))
printf("No Elment!\n");
else update(1,1,n,e,-1);
} else if(p==2) {
scanf("%d%d",&e,&k);
int t=q_sum(1,1,n,1,e)+k;
find_rt(1,1,n,t);
if(ans==n)
printf("Not Find!\n");
else
printf("%d\n",ans);
}
}
}
return 0;
}
5 0 5 1 2 0 6 2 3 2 2 8 1 7 0 2 0 2 0 4 2 1 1 2 1 2 2 1 3 2 1 4
No Elment! 6 Not Find! 2 2 4 Not Find!
HDU2852_KiKi's K-Number(线段树/单点更新),布布扣,bubuko.com
HDU2852_KiKi's K-Number(线段树/单点更新)
标签:des style http color java os io strong
原文地址:http://blog.csdn.net/juncoder/article/details/38473747