题意:有n个人,需要搞到全部n个人的票,搞到第i个人的票有两种方式:之前已经搞到mi个人的票,或者直接花费pi
问最小的搞到所有票的总代价
n<=2e5,1<=p[i]<=1e9,0<=m[i]<n
思路:考虑从大到小白嫖上限K
对于mi<=K的必定白嫖,对于mi>K的维护一个待定集合,设集合大小为size
当事实上已确定选的人数,即n-size>=K时方案合法
确定K之后需要减小size,即每次从size中选出pi最小的购买
因为待定集合一定是以mi为第一关键字从小到大排序的一个后缀,所以K需要懂大到小枚举
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef long double ld; 7 typedef pair<int,int> PII; 8 typedef pair<ll,ll> Pll; 9 typedef vector<int> VI; 10 typedef vector<PII> VII; 11 //typedef pair<ll,ll>P; 12 #define N 200010 13 #define M 200010 14 #define INF 1e9 15 #define fi first 16 #define se second 17 #define MP make_pair 18 #define pb push_back 19 #define pi acos(-1) 20 #define mem(a,b) memset(a,b,sizeof(a)) 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 23 #define lowbit(x) x&(-x) 24 #define Rand (rand()*(1<<16)+rand()) 25 #define id(x) ((x)<=B?(x):m-n/(x)+1) 26 #define ls p<<1 27 #define rs p<<1|1 28 29 const ll MOD=1e9+7,inv2=(MOD+1)/2; 30 double eps=1e-6; 31 int dx[4]={-1,1,0,0}; 32 int dy[4]={0,0,-1,1}; 33 34 vector<int> c[N]; 35 36 int read() 37 { 38 int v=0,f=1; 39 char c=getchar(); 40 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 41 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 42 return v*f; 43 } 44 45 void solve() 46 { 47 int n=read(); 48 rep(i,1,n) 49 { 50 int x=read(),y=read(); 51 c[x].pb(y); 52 } 53 ll ans=0; 54 priority_queue<int,VI,greater<int>> q; 55 per(i,n-1,0) 56 { 57 for(int j=0;j<c[i].size();j++) q.push(c[i][j]); 58 while(q.size()>n-i) 59 { 60 ans+=q.top(); 61 q.pop(); 62 } 63 } 64 rep(i,0,n-1) c[i].clear(); 65 printf("%I64d ",ans); 66 } 67 68 int main() 69 { 70 //freopen("1.in","r",stdin); 71 int cas=read(); 72 while(cas--) solve(); 73 return 0; 74 }