一句话题解:贪心+treap
好几天前刚学的treap,然后真到了考treap又写不出来,这么辣鸡还搞什么OI
先按$A_i$递减排序,然后把$C_i$也递减排序,然后用一个指针指向$M$序列,遍历$N$序列,这样的话每次所找到的元素必定是$A_i \leq B_i$的
这样我们就可以专注于$B_i$和$D_i$的关系,这个关系我们用平衡树维护就行了,Treap就是个不错的选择。每次插入合法的$C_i$,然后累加每个最优的$C_i$
具体参考代码:
//OJ 1939 //by Cydiater //2016.9.10 #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <ctime> #include <cmath> #include <string> #include <iomanip> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) ; const ll oo=0x3f3f3f3f; inline ll read(){ ,f=; ;ch=getchar();} +ch-';ch=getchar();} return x*f; } ,tol=,tmp; ll ans=; struct _data{ int x,y; }a[MAXN],b[MAXN]; struct tree{ int leftt,rightt,v,siz,cnt,rnd; }t[MAXN]; namespace solution{ inline bool cmpfory(_data x,_data y){return x.y>y.y;} inline void updata(int k){t[k].siz=t[t[k].leftt].siz+t[t[k].rightt].siz+t[k].cnt;} void init(){ N=read();M=read(); up(i,,N){ a[i].x=read();a[i].y=read(); } up(i,,M){ b[i].x=read();b[i].y=read(); } sort(a+,a+N+,cmpfory); sort(b+,b+M+,cmpfory); } void lefturn(int &k){ int tt=t[k].rightt;t[k].rightt=t[tt].leftt;t[tt].leftt=k; t[tt].siz=t[k].siz;updata(k);k=tt; } void righturn(int &k){ int tt=t[k].leftt;t[k].leftt=t[tt].rightt;t[tt].rightt=k; t[tt].siz=t[k].siz;updata(k);k=tt; } void insert(int &k,int v){ ){ k=++tol;t[k].leftt=t[k].rightt=; t[k].rnd=rand();t[k].v=v;t[k].siz=t[k].cnt=; return; } t[k].siz++; if(t[k].v==v){ t[k].cnt++; return; } if(v<t[k].v){ insert(t[k].leftt,v); if(t[k].rnd>t[t[k].leftt].rnd)righturn(k); }else if(v>t[k].v){ insert(t[k].rightt,v); if(t[k].rnd>t[t[k].rightt].rnd)lefturn(k); } } void nxt(int k,int v){ )return; if(t[k].v>=v){ tmp=t[k].v; nxt(t[k].leftt,v); }else nxt(t[k].rightt,v); } void del(int &k,int v){ )return; if(v==t[k].v){ ){ t[k].cnt--; t[k].siz--; return; } ){ k=t[k].leftt+t[k].rightt; return; } if(t[t[k].leftt].rnd<t[t[k].rightt].rnd){ righturn(k); del(k,v); }else{ lefturn(k); del(k,v); } } else if(v<t[k].v){ t[k].siz--; del(t[k].leftt,v); }else{ t[k].siz--; del(t[k].rightt,v); } } void slove(){ ; up(i,,N){ while(b[j].y>=a[i].y&&j<=M) insert(root,b[j++].x); tmp=-; nxt(root,a[i].x);ans+=tmp; ){ puts("-1"); exit(); } del(root,tmp); } } void output(){ cout<<ans<<endl; } } int main(){ //freopen("input.in","r",stdin); using namespace solution; init(); slove(); output(); ; }
另外,这个会爆ll