一眼贪心,先把每头牛的忍受范围变成区间
对于每个防晒霜,肯定优先给,能给的,区间右端点最小的
因为右端点大的之后还有更多机会,然后搞一个 $set$ 什么的乱维护一下就行
改了半天原来是要开 $multiset$ 啊
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<set> using namespace std; typedef long long ll; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } const int N=5007; int n,m,ans; struct cow{ int l,r; inline bool operator < (const cow &tmp) const { return l!=tmp.l ? l<tmp.l : r<tmp.r; } }C[N]; struct dat{ int pos,s; inline bool operator < (const dat &tmp) const { return pos<tmp.pos; } }D[N]; struct dat2{ int v; dat2 (int a=0) { v=a; } inline bool operator < (const dat2 &tmp) const { return C[v].r<C[tmp.v].r; } }; multiset <dat2> S; multiset <dat2>::iterator it; int main() { n=read(),m=read(); for(int i=1;i<=n;i++) C[i].l=read(),C[i].r=read(); for(int i=1;i<=m;i++) D[i].pos=read(),D[i].s=read(); sort(C+1,C+n+1); sort(D+1,D+m+1); int r=1; for(int i=1;i<=m;i++) { while( r<=n && C[r].l<=D[i].pos) S.insert(dat2(r)),r++; for(int j=1;j<=D[i].s;) { it=S.begin(); if(it==S.end()) break; if(C[(*it).v].r<D[i].pos) S.erase(it); else S.erase(it),ans++,j++; } } printf("%d ",ans); return 0; }