• bzoj 1691: [Usaco2007 Dec]挑剔的美食家【贪心+splay】


    高端贪心,好久没写splay调了好久……
    以下v为价格,w为鲜嫩度
    把牛和草都按v排升序,扫草,首先把v小于等于当前草的牛都丢进splay,这样一来splay里全是可选的牛了,按w排序,然后贪心的为当前的草取牛:w小于等于当前草的w的牛,取出来删除,ans加上当前草的价格(没有则跳过)
    取牛的时候统计一下来判无解

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=100005,inf=1e9+7;
    int n,m,tot,con,rot;
    struct phs
    {
    	int f,c[2],v,s;
    }t[N];
    struct qwe
    {
    	int v,w;
    }a[N],b[N];
    bool cmp(const qwe &a,const qwe &b)
    {
    	return a.v<b.v||(a.v==b.v&&a.w<b.w);;
    }
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    inline void ud(int x)
    {
    	t[x].s=t[t[x].c[0]].s+t[t[x].c[1]].s+1;
    }
    void zhuan(int x,int &k)
    {
    	int y=t[x].f,z=t[y].f,l=t[y].c[0]!=x,r=l^1;
    	if(y!=k)
    		t[z].c[t[z].c[0]!=y]=x;
    	else
    		k=x;
    	t[x].f=z;
    	t[y].c[l]=t[x].c[r];
    	t[t[y].c[l]].f=y;
    	t[x].c[r]=y;
    	t[y].f=x;
    	ud(y);
    	ud(x);
    }
    void splay(int x,int &k)
    {
    	while(x!=k)
    	{//cerr<<x<<" "<<k<<endl;
    		int y=t[x].f,z=t[y].f;
    		if(y!=k)
    		{
    			if((t[y].c[0]==x)^(t[z].c[0]==y))
    				zhuan(x,k);
    			else
    				zhuan(y,k);
    		}
    		zhuan(x,k);
    	}
    }
    int rnk(int x,int v)
    {//cerr<<"rnk"<<endl;
    	int re=0;
    	while(x)
    	{
    		if(t[x].v<=v)
    			re+=t[t[x].c[0]].s+1,x=t[x].c[1];
    		else
    			x=t[x].c[0];
    	}
    	return re;
    }
    int shu(int x,int k)
    {//cerr<<"shu"<<endl;
    	if(!x)
    		return 0;
    	if(t[t[x].c[0]].s+1==k)
    		return x;
    	else if(t[t[x].c[0]].s+1<k)
    		return shu(t[x].c[1],k-t[t[x].c[0]].s-1);
    	else
    		return shu(t[x].c[0],k);
    }
    void charu(int w)
    {//cerr<<"charu"<<" "<<w<<endl;
    	int x=shu(rot,rnk(rot,w));
    	splay(x,rot);
    	int y=shu(t[x].c[1],1);
    	splay(y,t[x].c[1]);
    	t[y].c[0]=++tot;
    	t[tot].f=y;
    	t[tot].v=w;
    	t[tot].s=1;
    	ud(y);
    	ud(x);
    }
    void shanchu(int rk)
    {//cerr<<"shanchu"<<endl;
    	int x=shu(rot,rk-1);
    	splay(x,rot);
    	int y=shu(t[x].c[1],2);
    	splay(y,t[x].c[1]);
    	t[t[y].c[0]].f=0;
    	t[y].c[0]=0;
    	ud(y);
    	ud(x);
    }
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)
    		a[i].v=read(),a[i].w=read();
    	for(int i=1;i<=m;i++)
    		b[i].v=read(),b[i].w=read();
    	sort(a+1,a+1+n,cmp);
    	sort(b+1,b+1+m,cmp);
    	long long ans=0;
    	t[1].f=2,t[1].s=1,t[1].v=-inf;
    	t[2].s=4,t[2].c[0]=1,t[2].c[1]=3,t[2].v=-inf;
    	t[3].f=2,t[3].c[0]=4,t[3].s=2,t[3].v=inf;
    	t[4].f=3,t[4].s=1,t[4].v=inf;
    	tot=4,rot=2;
    	for(int i=1,j=1;i<=m&&con<=n;i++)
    	{//cerr<<b[i].v<<" "<<b[i].w<<endl;
    		while(j<=n&&a[j].v<=b[i].v)
    			charu(a[j++].w);//,cerr<<a[j-1].v<<" "<<a[j-1].w<<endl;
    		int now=rnk(rot,b[i].w);//cerr<<b[i].w<<"   "<<now<<endl;
    		if(now>2)
    			ans+=b[i].v,con++,shanchu(now);//,cerr<<b[i].v<<" "<<b[i].w<<endl;cerr<<endl;
    	}//cerr<<ans<<endl;
    	printf("%lld
    ",con<n?-1ll:ans);
    	return 0;
    }
    
  • 相关阅读:
    JS时钟--星期 年 月 日 时 分
    [考试反思]0825NOIP模拟测试30:没落
    [考试反思]0822NOIP模拟测试29:延续
    [考试反思]0821NOIP模拟测试28:沉默
    小奇的仓库:换根dp
    短期Flag
    [考试反思]0820NOIP模拟测试27:幻影
    [考试反思]0819NOIP模拟测试26:荒芜
    0818NOIP模拟测试25——B卷简记
    [模板]tarjan——最后通牒
  • 原文地址:https://www.cnblogs.com/lokiii/p/8991323.html
Copyright © 2020-2023  润新知