HDU 4217 Data Structure?
题意: 有 n 个数,从做到到右依次为1..n,有m 组操作,每次输入一个值k,讲序列中的第k大元素取出,问最后取到的数字的和为多少。
分析: 线段树,num[] 表示该区间有多少个数。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define clr(x)memset(x,0,sizeof(x)) #define maxn 270000 int num[maxn<<3]; void creat(int l,int r,int rt) { if(l==r) { num[rt]=1; return; } int mid=(l+r)>>1; creat(l,mid,rt<<1); creat(mid+1,r,rt<<1|1); num[rt]=num[rt<<1]+num[rt<<1|1]; } int query(int k,int l,int r,int rt) { if(l==r) { num[rt]=0; return l; } int mid=(l+r)>>1; int res; if(num[rt<<1]<k) res=query(k-num[rt<<1],mid+1,r,rt<<1|1); else res=query(k,l,mid,rt<<1); num[rt]=num[rt<<1]+num[rt<<1|1]; return res; } int a[maxn]; int main() { int t,n,m,i,ca=1; __int64 ans; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); ans=0; creat(1,n,1); for(i=1;i<=n;i++) a[i]=i; while(m--) { int k; scanf("%d",&k); k=query(k,1,n,1); ans+=a[k]; } printf("Case %d: %I64d\n",ca++,ans); } return 0; }