线段树
1 #include<stdio.h> 2 #define MAXN 270000 3 int num[MAXN<<2]; 4 5 void build(int p,int l,int r) 6 { 7 num[p]=r-l+1; 8 if(l==r) 9 { 10 return; 11 } 12 int m=(l+r)/2; 13 build(p*2,l,m); 14 build(p*2+1,m+1,r); 15 } 16 17 int query(int tmp,int l,int r,int p) 18 { 19 num[p]-=1; //printf("now l:%d num[%d]:%d\n",l,p,num[p]); 20 if(l==r) 21 { 22 return l; 23 } 24 int m=(l+r)/2; 25 if(num[p*2]>=tmp) 26 return query(tmp,l,m,p*2); 27 else 28 return query(tmp-num[p*2],m+1,r,p*2+1); 29 } 30 31 int main() 32 { 33 int t; 34 scanf("%d",&t); 35 for(int c=1;c<=t;c++) 36 { 37 int n,k; 38 scanf("%d%d",&n,&k); 39 build(1,1,n); 40 __int64 sum=0; 41 //for(int i=1;i<=n;i++) 42 // printf("%d ",num[i]);printf("\n"); 43 for(int i=1;i<=k;i++) 44 { 45 int tmp;scanf("%d",&tmp); 46 sum+=query(tmp,1,n,1); 47 } 48 printf("Case %d: %I64d\n",c,sum); 49 } 50 return 0; 51 }