标签: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