zoukankan      html  css  js  c++  java
  • [BZOJ4569][SCOI2016]萌萌哒

    bzoj
    luogu

    sol

    维护(log{n})个并查集,每个限制就行(ST)表那样分成两个区间然后合并。
    接着把所有合并标记下方,最后就只要查第(0)个并查集里有几个代表元就好了。

    code

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 2e5+5;
    const int mod = 1e9+7;
    int n,m,lg[N],ans;
    struct bcj{
    	int fa[N];
    	void init(){for (int i=1;i<=n;++i) fa[i]=i;}
    	int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    	void merge(int i,int j){fa[find(i)]=find(j);}
    }S[18];
    int fastpow(int a,int b)
    {
    	int res=1;
    	while (b) {if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}
    	return res;
    }
    int main()
    {
    	n=gi();m=gi();
    	for (int i=2;i<=n;++i) lg[i]=lg[i>>1]+1;
    	for (int i=0;i<=lg[n];++i) S[i].init();
    	for (int i=1;i<=m;++i)
    	{
    		int a=gi(),b=gi(),c=gi(),d=gi(),k=lg[b-a+1];
    		S[k].merge(a,c);S[k].merge(b-(1<<k)+1,d-(1<<k)+1);
    	}
    	for (int j=lg[n];j;--j)
    		for (int i=1;i<=n;++i)
    		{
    			int x=S[j].find(i);
    			S[j-1].merge(i,x);S[j-1].merge(i+(1<<j-1),x+(1<<j-1));
    		}
    	for (int i=1;i<=n;++i) if (S[0].find(i)==i) ++ans;
    	printf("%lld
    ",9ll*fastpow(10,ans-1)%mod);return 0;
    }
    
  • 相关阅读:
    csuoj 1111: 三家人
    csu oj 1339: 最后一滴血
    csuoj 1337: 搞笑版费马大定理
    csuoj 1334: 好老师
    csu oj 1330 字符识别?
    C++动态内存分配
    变量内存分配
    codevs 2235 机票打折
    contesthunter CH Round #64
    面试分享:一年经验初探阿里巴巴前端社招
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8691310.html
Copyright © 2011-2022 走看看