#include<stdio.h> #include<string.h> #include<algorithm> #include<vector> using namespace std; struct node {int l,r,sum,cnt; }tr[400040]; vector<int>a[100005],g[100005]; int i,j,k,m,n,t,x,y; int cost; int cnt; void build(int L,int R,int num) {tr[num].l=L; tr[num].r=R; if(L==R) {tr[num].sum=0; tr[num].cnt=0; } else {build(L,(L+R)/2,2*num); build((L+R)/2+1,R,2*num+1); tr[num].sum=tr[num*2+1].sum+tr[num*2].sum; tr[num].cnt=tr[num*2+1].cnt+tr[num*2].cnt; } } void add(int x,int y,int num) { if(tr[num].l==tr[num].r) { tr[num].sum+=x*y; tr[num].cnt+=y; return ; } if(x>(tr[num].l+tr[num].r)/2)add(x,y,num*2+1); if(x<=(tr[num].l+tr[num].r)/2)add(x,y,num*2); tr[num].sum=tr[num*2+1].sum+tr[num*2].sum; tr[num].cnt=tr[num*2+1].cnt+tr[num*2].cnt; } int query(int k,int num) { if(k<0)return 0; if(tr[num].cnt<=k)return tr[num].sum; if(tr[num].l==tr[num].r) return min(k,tr[num].cnt)*tr[num].l; if(tr[num*2].cnt>=k) return query(k,num*2); else return tr[num*2].sum+query(k-tr[num*2].cnt,num*2+1); } int main() { scanf("%d",&n); build(0,100004,1); cnt=0,cost=0; for(int i=0;i<=100000;i++) { a[i].clear(); g[i].clear(); } for(int i=1;i<=n;i++) { int u,v; scanf("%d%d",&u,&v); a[u].push_back(v); add(v,1,1); } { scanf("%d",&k); printf("%d\n",query(k,1)); }*/ for(int i=0;i<=100002;i++)sort(a[i].begin(),a[i].end()); for(int i=0;i<=100002;i++) for(int j=0;j<a[i].size();j++) g[a[i].size()-j].push_back(a[i][j]); printf("%d:%d\n",i,g[i].size());*/ int minn=1e9+1; for(int i=n;i>=0;i--) { for(int j=0;j<g[i].size();j++) { cost+=g[i][j]; cnt++; add(g[i][j],-1,1); } //printf("query:%d\n",query(1,1)); if(cnt>=i)minn=min(minn,cost); else minn=min(minn,query(i-cnt,1)+cost); //printf("x:%d cnt:%d cost:%d minn:%d\n",i,cnt,cost,minn); } printf("%d\n",minn); return 0; }
|