【BZOJ】1691: [Usaco2007 Dec]挑剔的美食家
【算法】扫描线+平衡树(set)
【题解】很明显的二维偏序数点,排序后扫描线,现加点后查询答案。
则问题转化为一维偏序,显然贪心找第一个比当前大的最优,所以用平衡树维护。
记得开multiset!!!
#include<cstdio> #include<algorithm> #include<cstring> #include<set> #include<cctype> using namespace std; const int maxn=100010; int n,m,tot; long long ans=0; struct cyc{int x,y,p;}b[maxn*2]; multiset<int>s; multiset<int>::iterator it;//!!! int read() { char c;int s=0,t=1; while(!isdigit(c=getchar()))if(c=='-')t=-1; do{s=s*10+c-'0';}while(isdigit(c=getchar())); return s*t; } bool cmp(cyc a,cyc b){return a.y>b.y||(a.y==b.y&&a.p>b.p);} int main(){ n=read();m=read(); tot=0; for(int i=1;i<=n;i++){//mat int u=read(),v=read(); b[++tot]=(cyc){u,v,0}; } for(int i=1;i<=m;i++){//point int u=read(),v=read(); b[++tot]=(cyc){u,v,1}; } sort(b+1,b+tot+1,cmp); for(int i=1;i<=tot;i++){ if(b[i].p){ s.insert(b[i].x); } else{ it=s.lower_bound(b[i].x); if(it==s.end()){ans=-1;break;} ans+=*it; s.erase(it); } } printf("%lld",ans); return 0; }