zoukankan      html  css  js  c++  java
  • 洛谷 P5328 [ZJOI2019]浙江省选

    洛谷 P5328 [ZJOI2019]浙江省选

    https://www.luogu.com.cn/problem/P5328

    UErYM4.png

    UErwIx.png

    Tutorial

    https://www.luogu.com.cn/blog/foreverlasting/solution-p5328

    每个选手可以看作一条(y=a_ix+b_i)的直线,他的最好名次就是找到一个非负整数(x),使得此时严格在它上面的直线数+1最小.

    那么,如果想要找到所有名次=1的选手,那么做一次半平面交,即可得到那些选手,注意由于(x)只能是非负整数,所以需要在弹出需要的是考虑那条直线是否有整点在轮廓上,需要向上取整和向下取整的操作,所以本题就用分数储存浮点数.

    在那之后,如果我们将所有名次=1的选手的直线删去,那么名次=2的选手也可以做一次半平面交,但注意此时轮廓上的不一定是名次=2的,因为对于某个(x),可能有多个名次=1在它之上.

    可以对于此时所有已经有名次的直线,二分计算它在当前轮廓线上方的(x)的范围,然后通过差分就可以得到当前(x)有多少个直线在其上方.

    之后就枚举轮廓线上的每一条直线,如果它的范围中存在(x)使在其上方直线数=当前名次数-1,那么它的最好名次就是当前名次

    Code

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #define debug(...) fprintf(stderr,__VA_ARGS__)
    #define fi first
    #define se second
    using namespace std;
    inline char gc() {
    //	return getchar();
    	static char buf[100000],*l=buf,*r=buf;
    	return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
    }
    template<class T> void rd(T &x) {
    	x=0; int f=1,ch=gc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    	while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=gc();}
    	x*=f;
    }
    typedef long long ll;
    const ll INF=2e18;
    const int maxn=1e5+50;
    int n,m,an[maxn];
    struct Line {
    	int k,id; ll b;
    	bool operator <(const Line &other) const {
    		if(k!=other.k) return k<other.k;
    		return b>other.b;
    	}
    } L[maxn]; 
    struct Frac {
    	ll a,b,c;
    	Frac() {a=b=0,c=1;}
    	Frac(ll x,ll y) {
    		if(y<0) x=-x,y=-y;
    		a=x/y,b=x%y,c=y;
    		if(b<0) b+=y,--a;
    	}
    	inline bool operator <(const Frac &other) const {
    		if(a!=other.a) return a<other.a;
    		return b*other.c<other.b*c;
    	}
    	friend inline bool operator <=(const Frac &a,const Frac &b) {return !(b<a);}
    	inline ll fl() {return a;}
    	inline ll cl() {return a+bool(b);}
    };
    inline Frac crosP(Line u,Line v) {
    	return Frac(u.b-v.b,v.k-u.k);
    }
    void sol(int now) {
    	static Line q[maxn]; static Frac p[maxn]; int top=0;
    	for(int i=1,j=-1;i<=n;++i) if(an[L[i].id]==-1) {
    		if(top&&L[i].k==q[top].k) continue;
    		while(top&&crosP(q[top],L[i]).fl()<p[top].cl()) --top;
    		q[++top]=L[i];
    		if(top>1) p[top]=crosP(q[top],q[top-1]);
    	}
    	p[top+1]=Frac(INF,1);
    	vector< pair<ll,int> > tag; 
    	for(int i=1;i<=n;++i) if(an[L[i].id]!=-1) {
    		{
    			int l=1,r=top,re=-1;
    			while(l<=r) {
    				int mid=(l+r)>>1;
    				if(q[mid].k>=L[i].k||crosP(L[i],q[mid])<=p[mid+1]) re=mid,r=mid-1;
    				else l=mid+1;
    			}
    			if(re!=-1&&q[re].k<L[i].k) tag.push_back(make_pair(crosP(L[i],q[re]).fl()+1,1));
    			else tag.push_back(make_pair(0,1));
    		}
    		{
    			int l=1,r=top,re=-1;
    			while(l<=r) {
    				int mid=(l+r)>>1;
    				if(q[mid].k<=L[i].k||p[mid]<=crosP(L[i],q[mid])) re=mid,l=mid+1;
    				else r=mid-1;
    			}
    			if(re!=-1&&q[re].k>L[i].k) tag.push_back(make_pair(crosP(L[i],q[re]).cl(),-1));
    		}
    	}
    	sort(tag.begin(),tag.end());
    	for(int i=1,k=0,cnt=0;i<=top;++i) {
    		while(k<tag.size()&&tag[k].fi<=p[i].cl()) cnt+=tag[k++].se;
    		if(cnt==now-1) an[q[i].id]=now;
    		while(k<tag.size()&&tag[k].fi<=p[i+1].fl()) {
    			int j=k; while(j<tag.size()&&tag[j].fi==tag[k].fi) cnt+=tag[j++].se;
    			if(cnt==now-1) an[q[i].id]=now;
    			k=j;
    		}
    	}
    }
    int main() {
    	rd(n),rd(m);
    	for(int i=1;i<=n;++i) {
    		rd(L[i].k),rd(L[i].b);
    		L[i].id=i;
    	}
    	sort(L+1,L+n+1);
    	memset(an,-1,sizeof(an));
    	for(int i=1;i<=m;++i) sol(i);
    	for(int i=1;i<=n;++i) {
    		if(i!=1) printf(" ");
    		printf("%d",an[i]);
    	}
    	printf("
    ");
    	return 0;
    } 
    
  • 相关阅读:
    还有为window.close()方法弹出的询问窗口烦?
    ValidateTextBox发布绝对实用
    面向对象设计的11个原则
    关于建立控件、组件开发团队,有兴趣的网友请留言
    存储过程和触发器要使用链接服务器时要注意的一点
    “这块布的艺术成分都几高唧!”“有几高啊?”“三、四层楼那么高啦。”
    有没有人用过负离子发生器?
    摇滚你的页面。Free:RockUControl控件发布,开源:RevealTransitionImage
    控件开发团队序言及加入说明
    一些平时能用到的CSS效果(ZT+YC)
  • 原文地址:https://www.cnblogs.com/ljzalc1022/p/13265477.html
Copyright © 2011-2022 走看看