Problem: http://acm.hdu.edu.cn/showproblem.php?pid=4217
给定1~n的n个数
依次求第ki小的数 删除该数 再求剩下的数中第ki+1小的数 删除...
求所有删除的数的和
用树状数组bit[]:bit[k](这里的bit[k]不是bit[k]本身的值,详见代码中find(k))表示小于等于 k 的数的个数
用二分搜索 搜索第ki大的数
#include<cstdio> const int MAXN=270000; int bit[MAXN]; int find(int k){//查找小于等于k的数的个数 int ret=0; while(k>0){ ret+=bit[k]; k-=k&-k; } return ret; } int work(int k,int n){ int L=1,R=n; while(L<R){//二分搜索第k大的值 int M=(L+R)>>1; if(k>find(M))L=M+1; else R=M; } while(R<=n){//删除第k大的值 在树状数组中的形式为比k大的数 的bit[]-1 bit[R]--; R+=R&-R; } return L; } int main() { int t,n,k,ki; scanf("%d",&t); for(int Case=1;Case<=t;Case++){ scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)bit[i]=i&-i;//树状数组实现 long long ans=0; for(int i=0;i<k;i++){ scanf("%d",&ki); ans+=work(ki,n); } printf("Case %d: %I64d ",Case,ans); } return 0; }
想想 此题线段树、平衡数应该都可做