经历一天学一课的期末考试后 队友让我写写题找找手感....
这题....很裸 一眼multiset...但是教主的备注是splay 那就正好练手感呗...写了一个假贪心...太菜了....
题解:考虑到对于草和奶牛 按照新鲜度从大到小排序 对于每头奶牛找到当前的新鲜度里面最小的价格就ok了 对于每个奶牛操作前 将新鲜度大于等于他的鲜草加入到splay中 查询即可
#include <bits/stdc++.h>
const int MAXN=2e5+10;
const int inf=1e9+21;
#define ll long long
using namespace std;
int ch[MAXN][2],size[MAXN],key[MAXN],root,pre[MAXN],p[MAXN];
int S[MAXN],tot;
int cnt;
void Treavel(int x)
{
if(x)
{
Treavel(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d\n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
Treavel(ch[x][1]);
}
}
void debug(int rp)
{
printf("root:%d\n",rp);
Treavel(rp);
}
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar();
return f*x;
}
typedef struct Splay{
int maxx,pos,pos1;
void newnode(int &x,int y,int vul,int t){
if(tot)x=S[tot--];
else x=++cnt;
p[x]=t;
ch[x][0]=ch[x][1]=0;pre[x]=y;size[x]=1;key[x]=vul;
}
void inte(){
newnode(root,0,-1*inf,0);
newnode(ch[root][1],root,inf,0);
}
void up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}
void rotate(int x,int kind){
int y=pre[x];
pre[ch[x][kind]]=y;ch[y][!kind]=ch[x][kind];
if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
up(y);up(x);
}
void splay(int x,int goal){
while(pre[x]!=goal){
if(pre[pre[x]]==goal)rotate(x,ch[pre[x]][0]==x);
else{
int y=pre[x];int kind=ch[pre[y]][0]==y;
if(ch[y][kind]==x)rotate(x,!kind),rotate(x,kind);
else rotate(y,kind),rotate(x,kind);
}
}
if(goal==0)root=x;
}
int find1(int x,int sz){
if(sz==size[ch[x][0]]+1)return x;
else if(sz<=size[ch[x][0]])return find1(ch[x][0],sz);
else return find1(ch[x][1],sz-size[ch[x][0]]-1);
}
int find2(int x,int vul,int t){
if(!x)return 0;
if(vul==key[x]&&t==p[x])return x;
else if(vul==key[x]&&t<p[x])return find2(ch[x][0],vul,t);
else if(vul==key[x]&&t>p[x])return find2(ch[x][1],vul,t);
else if(vul<key[x])return find2(ch[x][0],vul,t);
else return find2(ch[x][1],vul,t);
}
void destory(int x){
if(!x)return ;
splay(x,0);int sz=size[ch[x][0]];
splay(find1(root,sz),0);
splay(find1(root,sz+2),root);
S[++tot]=ch[ch[root][1]][0];
ch[ch[root][1]][0]=0;up(ch[root][1]);up(root);
}
void last_node(int x,int vul){
if(!x)return ;
if(key[x]<vul)last_node(ch[x][1],vul);
else{
if(key[x]<maxx||(key[x]==maxx&&pos1>p[x]))maxx=key[x],pos=x,pos1=p[x];
last_node(ch[x][0],vul);
}
}
void insert(int &x,int vul,int fa,int t){
if(!x){newnode(x,fa,vul,t);return ;}
if(key[x]>vul)insert(ch[x][0],vul,x,t);
else insert(ch[x][1],vul,x,t);
up(x);
}
}Splay;
int n,m;
typedef struct node{
int x,y;
friend bool operator<(node aa,node bb){return aa.y>bb.y;}
}node;
bool cmp(node aa,node bb){
return aa.y>bb.y;
}
node a[MAXN],b[MAXN];
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)a[i].x=read(),a[i].y=read();
for(int i=1;i<=m;i++)b[i].x=read(),b[i].y=read();
if(n>m){puts("-1");return 0;}
sort(a+1,a+n+1,cmp);sort(b+1,b+1+m);
Splay T;T.inte();
//for(int i=1;i<=m;i++){T.insert(root,b[i].x,0,i);T.splay(cnt,0);}
int l=1;ll ans=0;
for(int i=1;i<=n;i++){
while(l<=m&&b[l].y>=a[i].y){T.insert(root,b[l].x,0,l);l++;}
// debug(root);
//if(l>m){puts("-1");return 0;}
T.maxx=inf;T.pos1=inf;T.last_node(root,a[i].x);
if(T.maxx==inf){puts("-1");return 0;}
ans+=T.maxx;T.destory(T.pos);
// debug(root);
}
printf("%lld\n",ans);
return 0;
}
与很多奶牛一样,Farmer
John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一去不返了。现在,Farmer
John不得不去牧草专供商那里购买大量美味多汁的牧草,来满足他那N(1 <= N <= 100,000)头挑剔的奶牛。
所有奶牛都对FJ提出了她对牧草的要求:第i头奶牛要求她的食物每份的价钱不低于A_i(1 <= A_i <=
1,000,000,000),并且鲜嫩程度不能低于B_i(1 <= B_i <= 1,000,000,000)。商店里供应M(1
<= M <= 100,000)种不同的牧草,第i 种牧草的定价为C_i(1 <= C_i <=
1,000,000,000),鲜嫩程度为D_i (1 <= D_i <= 1,000,000,000)。
为了显示她们的与众不同,每头奶牛都要求她的食物是独一无二的,也就是说,没有哪两头奶牛会选择同一种食物。 Farmer
John想知道,为了让所有奶牛满意,他最少得在购买食物上花多少钱。
* 第1行: 2个用空格隔开的整数:N 和 M
* 第2..N+1行: 第i+1行包含2个用空格隔开的整数:A_i、B_i * 第N+2..N+M+1行: 第j+N+1行包含2个用空格隔开的整数:C_i、D_i
* 第1行: 输出1个整数,表示使所有奶牛满意的最小花费。如果无论如何都无法 满足所有奶牛的需求,输出-1