hdu 4217
想了很久,才知道用线段树来做,实现也不算太复杂。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define SIZE 262145 struct node { int i,left,right,sum; }; node vert[SIZE<<2]; int treeNode; int build(int i,int left,int right) { int mid; vert[i].left=left; vert[i].right=right; vert[i].sum=right-left+1; if(left==right) { vert[i].i=++treeNode; return 0; } mid=(left+right)>>1; build(i<<1,left,mid); build((i<<1)+1,mid+1,right); return 0; } int query(int i,int n,int goal) { int res; if(vert[i].left==vert[i].right) { vert[i].sum=0; return vert[i].i; } if(goal <= vert[i<<1].sum) { res = query(i<<1,n,goal); } else { res = query((i<<1)+1,n,goal-vert[i<<1].sum); } vert[i].sum--; return res; } int main() { int i,k,m,n,inum,count=0; __int64 sum; scanf("%d",&inum); while(inum--) { count++; sum=0; treeNode=0; scanf("%d %d",&n,&m); build(1,1,n); for(i=0;i<m;i++) { scanf("%d",&k); sum+=query(1,n,k); } printf("Case %d: %I64d\n",count,sum); } return 0; }