• [JOISC 2017 Day1] 港口设施


    一、题目

    点此看题

    二、解法

    首先考虑只有一个港口的情况,发现合法的充要条件是所有 \([a,b]\) 不交。

    由于两个港口是独立的,所以问题转化成:求出有多少种二染色方案,使得同色的线段不交。我们把满足 \(a<c<b<d\) 的线段 \([a,b]\)\([c,d]\) 之间连一条边,然后问题就变成了求连通块个数或者判断无解。

    暴力连边是 \(O(n^2)\) 的,这东西貌似不太好线段树优化建图。我们考虑按右端点从小到大扫描所有线段 \([a,b]\),并且维护右端点更大的线段组成的集合 \(S\),那么当前点连接的点是 \(S\) 中的一段连续区间(左端点在 \([a,b]\) 中)

    一个关键的 \(\tt observation\) 是:一段区间被连接后的效果是,区间中的点必然同色

    所以可以维护 \(nx_i\) 表示和点 \(i\) 同色的点最多延伸到哪里,那么修改变成暴力访问一段区间,并且把这段区间的 \(nx\) 全部指向区间的右端点。这等价于访问一条链并且修改它们的 \(fa\) 为链顶,所以可以套用并查集路径压缩的复杂度分析

    具体实现中,把左右端点拍到数轴上,然后扫描这个数轴。如果遇到左端点就把它加入 \(S\) 中,如果遇到右端点就区间连边,并且把它从 \(S\) 中删除,维护 \(S\) 也可以用并查集。时间复杂度 \(O(n\log n)\)

    #include <cstdio>
    #include <vector>
    using namespace std;
    const int M = 2000005;
    const int MOD = 1e9+7;
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int n,m,k,a[M],b[M],c[M],l[M],nx[M],fa[M];
    vector<int> g[M];
    int find(int x)
    {
    	if(x!=fa[x]) fa[x]=find(fa[x]);
    	return fa[x];
    }
    int qkpow(int a,int b)
    {
    	int r=1;
    	while(b>0)
    	{
    		if(b&1) r=1ll*r*a%MOD;
    		a=1ll*a*a%MOD;
    		b>>=1;
    	}
    	return r;
    }
    int dfs(int u)
    {
    	for(int v:g[u])
    	{
    		if(~c[v])
    		{
    			if(c[v]==c[u]) return 0;
    			continue;
    		}
    		c[v]=c[u]^1;if(!dfs(v)) return 0;
    	}
    	return 1;
    }
    signed main()
    {
    	n=read();
    	for(int i=1;i<=n;i++)
    		b[read()]=b[read()]=i,c[i]=-1;
    	for(int i=1;i<=2*n;i++)
    		fa[i]=nx[i]=i;
    	for(int i=1;i<=2*n;i++)
    	{
    		int u=b[i];
    		if(!l[u]) {a[++m]=u,l[u]=m;continue;}
    		for(int j=fa[l[u]]=find(l[u]+1);j<=m;)
    		{
    			g[a[j]].push_back(u);
    			g[u].push_back(a[j]);
    			int t=find(nx[j]+1);nx[j]=m;j=t;
    		}
    	}
    	for(int i=1;i<=n;i++)
    		if(c[i]==-1 && (k++,c[i]=0,!dfs(i)))
    			{puts("0");return 0;}
    	printf("%d\n",qkpow(2,k));
    }
    
  • 相关阅读:
    实操ES6之Promise
    RabbitMQ入门指南
    【从零开始撸一个App】PKCE
    SpringCloud Alibaba Nacos Config 配置中心
    SpringCloud Alibaba Nacos 服务发现 Feign进行消费
    SpringCloud Alibaba Nacos 服务发现 RestTemplate进行消费
    SpringCloud Alibaba Nacos 服务注册
    SpringCloud Alibaba Nacos 服务治理中心
    开发者-管理者 设计陷阱
    java8中的Stream API实战
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/16367385.html
Copyright © 2020-2023  润新知