[TJOI2013]奖学金

暴力前缀 

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int C=2*(1e5+7);
int n,f,c,node_cnt=0,rt[C],lc[C<<5],rc[C<<5],sum[C<<5],p,s,b[C];
struct people{
	int mark,money;
	#define k(x) a[x].mark
	#define m(x) a[x].money
}a[C];
inline bool cmp(const people &x,const people &y){
	return x.mark<y.mark;
}
inline void build(int &k,int l,int r){
	k=node_cnt++;
	if(l==r) return;
	int mid=(l+r)/2;
	build(lc[k],l,mid);
	build(rc[k],mid+1,r);
}
inline int modify(int k,int l,int r){
	 int oo=++node_cnt;
	 lc[oo]=lc[k];rc[oo]=rc[k];sum[oo]=sum[k]+1;
	 if(l==r) return oo;
	 int mid=(l+r)/2;
	 if(p<=mid) lc[oo]=modify(lc[oo],l,mid);
	 else rc[oo]=modify(rc[oo],mid+1,r);
	 return oo;
}
inline int query(int u,int v,int l,int r,int k){
	int mid=(l+r)/2,cnt=sum[lc[v]]-sum[lc[u]],ans;
	if(l==r) return l;
	if(k<=cnt) ans=query(lc[u],lc[v],l,mid,k);
	else ans=query(rc[u],rc[v],mid+1,r,k-cnt);
	return ans;
}
int main(){
	scanf("%d%d%d",&n,&c,&f);
	for(register int i=1;i<=c;i++){
		scanf("%d%d",&k(i),&m(i));
		b[i]=m(i);
	}
	sort(a+1,a+c+1,cmp);
	sort(b+1,b+c+1);
	int q=unique(b+1,b+c+1)-b-1;
	build(rt[0],1,q);
	for(register int i=1;i<=c;i++){
		p=lower_bound(b+1,b+q+1,m(i))-b;
		rt[i]=modify(rt[i-1],1,q);
    }
    for(register int i=c-n/2;i>=n/2;i--){
    	s=m(i);
    	for(int j=n/2;j>=1;j--){
    		s+=b[query(rt[0],rt[i-1],1,q,j)];
    		if(s>f) break;
    	}
    	if(s<=f){
    		cout<<s;
    		return 0;
    	}
    }
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_42198700/article/details/88952246