zoukankan      html  css  js  c++  java
  • 【CF471E】MUH and Lots and Lots of Segments 扫描线+并查集+线段树+set

    【CF471E】MUH and Lots and Lots of Segments

    题意:给你平面上n条水平或竖直的,端点在整点处的线段。你需要去掉一些线段的一些部分,使得剩下的图形:1.连通,2.无环,3.端点依旧位于整点处。

    $nle 2 imes 10^5$

    题解:如果把整点看成点的话,那么这题让你求的就是一棵生成树。一棵生成树的边数就是这个连通块内点数-1,所以我们找到最大的连通块将其点数-1就是答案。

    具体实现中,我们先进行扫描线,用并查集维护连通性,用线段树快速查找区间中点的数量以及一个点的前驱后继,用set维护所有所在连通块与后继所在连通块不同的点即可。

    不知道为什么思考的过程中想到了Kruskal。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #define lson x<<1
    #define rson x<<1|1
    using namespace std;
    const int maxn=200010;
    typedef long long ll;
    int n,m,np,nq;
    int f[maxn<<1],org[maxn<<1];
    ll ans;
    ll ref[maxn<<1];
    struct edge
    {
    	int l,r,x;
    }p[maxn],q[maxn<<1];
    ll s[maxn<<3],sum[maxn<<1];
    set<int> st;
    set<int>::iterator it;
    bool cmp(const edge &a,const edge &b)
    {
    	return (a.x==b.x)?(a.r>b.r):(a.x<b.x);
    }
    int find(int x)
    {
    	return (f[x]==x)?x:(f[x]=find(f[x]));
    }
    void updata(int l,int r,int x,int a,int b)
    {
    	s[x]+=b;
    	if(l==r)	return ;
    	int mid=(l+r)>>1;
    	if(a<=mid)	updata(l,mid,lson,a,b);
    	else	updata(mid+1,r,rson,a,b);
    }
    int count(int l,int r,int x,int a,int b)
    {
    	if(a>b)	return 0;
    	if(a<=l&&r<=b)	return s[x];
    	int mid=(l+r)>>1;
    	if(b<=mid)	return count(l,mid,lson,a,b);
    	if(a>mid)	return count(mid+1,r,rson,a,b);
    	return count(l,mid,lson,a,b)+count(mid+1,r,rson,a,b);
    }
    int find(int l,int r,int x,int a)
    {
    	if(l==r)	return l;
    	int mid=(l+r)>>1;
    	if(a<=s[lson])	return find(l,mid,lson,a);
    	return find(mid+1,r,rson,a-s[lson]);
    }
    inline int pre(int x)
    {
    	int t=count(1,m,1,1,x);
    	if(t==1)	return -1;
    	return find(1,m,1,t-1);
    }
    inline int nxt(int x)
    {
    	int t=count(1,m,1,1,x);
    	if(t==s[1])	return -1;
    	return find(1,m,1,t+1);
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+(gc^'0'),gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	n=rd();
    	int i,j,a,b,c,d;
    	ll tmp;
    	for(i=1;i<=n;i++)
    	{
    		a=rd(),b=rd(),c=rd(),d=rd();
    		if(b==d)
    		{
    			q[++nq].x=a,q[nq].l=b,q[nq].r=c-a+1;
    			q[++nq].x=c,q[nq].l=b,q[nq].r=0;
    			ref[++m]=b;
    		}
    		else
    		{
    			p[++np].x=a,p[np].l=b,p[np].r=d;
    			ref[++m]=b,ref[++m]=d;
    			ans=max(ans,ll(d-b));
    		}
    	}
    	sort(ref+1,ref+m+1);
    	for(i=1,j=0,ref[0]=-1<<30;i<=m;i++)	if(ref[i]!=ref[j])	ref[++j]=ref[i];
    	m=j;
    	for(i=1;i<=nq;i++)	q[i].l=lower_bound(ref+1,ref+m+1,q[i].l)-ref,f[i]=i;
    	for(i=1;i<=np;i++)	p[i].l=lower_bound(ref+1,ref+m+1,p[i].l)-ref,p[i].r=lower_bound(ref+1,ref+m+1,p[i].r)-ref;
    	sort(p+1,p+np+1,cmp);
    	sort(q+1,q+nq+1,cmp);
    	for(i=j=1;i<=np;i++)
    	{
    		while(j<=nq&&(q[j].x<p[i].x||(q[j].x==p[i].x&&q[j].r)))
    		{
    			a=q[j].l,b=q[j].r;
    			if(b)
    			{
    				org[a]=j,sum[j]=b;
    				st.insert(a);
    				updata(1,m,1,a,1);
    				c=pre(a);
    				if(c!=-1)	st.insert(c);
    			}
    			else
    			{
    				it=st.find(a);
    				if(it!=st.end())	st.erase(it);
    				c=pre(a);
    				if(c!=-1)	st.insert(c);
    				updata(1,m,1,a,-1);
    			}
    			j++;
    		}
    		tmp=ref[p[i].r]-ref[p[i].l]+1-count(1,m,1,p[i].l,p[i].r);
    		a=p[i].l-1,c=nxt(a);
    		if(c<=p[i].r)
    		{
    			sum[find(org[c])]+=tmp;
    			while(1)
    			{
    				it=st.lower_bound(p[i].l);
    				if(it==st.end()||(*it)>p[i].r)	break;
    				a=*it,c=nxt(a);
    				if(c==-1||c>p[i].r)	break;
    				st.erase(it);
    				b=find(org[a]),d=find(org[c]);
    				if(b!=d)	sum[d]+=sum[b],f[b]=d;
    			}
    		}
    	}
    	for(i=1;i<=nq;i++)	ans=max(ans,sum[i]-1);
    	printf("%lld",ans);
    	return 0;
    }
  • 相关阅读:
    201771010135 杨蓉庆《面对对象程序设计(java)》第十五周学习总结
    201771010135 杨蓉庆/张燕/杨玲《面对对象程序设计(java)》第十四周学习总结
    201771010135 杨蓉庆/张燕《面对对象程序设计(java)》第十三周学习总结
    团队作业6—复审与事后分析
    团队作业6——Alpha阶段项目复审
    团队作业6——事后分析
    团队作业5——测试与发布(Alpha版本)
    团队作业4-项目汇总
    团队作业4-Day7
    团队作业4-Day6
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/8685695.html
Copyright © 2011-2022 走看看