zoukankan      html  css  js  c++  java
  • ARC 062 F

    LINK:Painting Graphs with AtCoDeer

    看英文题面果然有点吃不消 一些细节会被忽略掉。

    问每条边都要被染色 且一个环上边的颜色可以旋转.

    用c种颜色有多少本质不同的方法。

    注意这里的环指简单环 即不能经过一个节点两次。

    考虑环套环的情况 手玩可以发现 可以将这种情况出现的所有边按顺序放置。

    那么只和颜色出现的次数有关 隔板法做即可。

    一个环 容易发现可以使用(burnside)引理。

    割边 也很容易。

    难点是求简单环。

    不能求割边 因为边双不一定是简单环。

    但是点双可以发现是简单环 证明可以感性理解 我也不知道怎么证明。

    再跑个割边求就复杂了。这道题特殊性是 无重边无自环。

    割边所属的那两个点显然是一个点双 所以这道题中大小为2的点双中间夹的就是割边。

    复杂度(n^2logn)

    code
    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<ctime>
    #include<cctype>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<ctime>
    #include<cmath>
    #include<cctype>
    #include<cstdlib>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<utility>
    #include<bitset>
    #include<set>
    #include<map>
    #define ll long long
    #define db double
    #define INF 10000000000000000ll
    #define inf 1000000000
    #define ldb long double
    #define pb push_back
    #define put_(x) printf("%d ",x);
    #define get(x) x=read()
    #define gt(x) scanf("%d",&x)
    #define gi(x) scanf("%lf",&x)
    #define put(x) printf("%d
    ",x)
    #define putl(x) printf("%lld
    ",x)
    #define rep(p,n,i) for(RE int i=p;i<=n;++i)
    #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
    #define fep(n,p,i) for(RE int i=n;i>=p;--i)
    #define vep(p,n,i) for(RE int i=p;i<n;++i)
    #define pii pair<int,int>
    #define mk make_pair
    #define RE register
    #define P 1000000007ll
    #define gf(x) scanf("%lf",&x)
    #define pf(x) ((x)*(x))
    #define uint unsigned long long
    #define ui unsigned
    #define EPS 1e-10
    #define sq sqrt
    #define S second
    #define F first
    #define mod 1000000007
    using namespace std;
    char *fs,*ft,buf[1<<15];
    inline char gc()
    {
    	return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
    }
    inline int read()
    {
    	RE int x=0,f=1;RE char ch=gc();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
    	return x*f;
    
    }
    const int MAXN=55,maxn=110<<2;
    int n,m,c,len=1,maxx,top,cc,cnt,T,ans=1;
    int fac[maxn],inv[maxn],vis[maxn],mark[maxn],dfn[maxn],low[maxn],s[maxn],g[maxn],q[maxn];
    int lin[MAXN],ver[maxn],nex[maxn];
    inline void add(int x,int y)
    {
    	ver[++len]=y;
    	nex[len]=lin[x];
    	lin[x]=len;
    }
    inline int ksm(int b,int p)
    {
    	int cnt=1;
    	while(p)
    	{
    		if(p&1)cnt=(ll)cnt*b%mod;
    		b=(ll)b*b%mod;p=p>>1;
    	}
    	return cnt;
    }
    inline int gcd(int a,int b){return b?gcd(b,a%b):a;}
    inline int solve(int n)
    {
    	int sum=0;
    	rep(1,n,i)sum=(sum+ksm(c,gcd(n,i)))%mod;
    	sum=(ll)sum*ksm(n,mod-2)%mod;
    	return sum;
    }
    inline int C(int a,int b){return a<b?0:fac[a]*(ll)inv[b]%mod*inv[a-b]%mod;}
    inline void solve_1(int n)
    {
    	if(n==2)return ++cnt,void();
    	rep(1,n,i)mark[q[i]]=1;
    	int sum=0;
    	rep(1,n,j)
    	{
    		for(int k=lin[q[j]];k;k=nex[k])
    		{
    			int tn=ver[k];
    			if(mark[tn])++sum;
    		}
    	}
    	sum=sum>>1;
    	if(sum==n)ans=(ll)ans*solve(n)%mod;
    	else ans=(ll)ans*C(c+sum-1,c-1)%mod;
    	rep(1,n,j)mark[q[j]]=0;
    }
    inline void dfs(int x)
    {
    	dfn[x]=low[x]=++T;s[++top]=x;
    	go(x)
    	{
    		if(!dfn[tn])
    		{
    			dfs(tn);
    			low[x]=min(low[x],low[tn]);
    			int tt=0;
    			if(low[tn]>=dfn[x])
    			{
    				int y=0;tt=0;
    				while(y!=tn)
    				{
    					y=s[top--];
    					q[++tt]=y;
    				}
    				q[++tt]=x;
    				solve_1(tt);
    			}
    		}
    		else low[x]=min(low[x],dfn[tn]);
    	}
    }
    int main()
    {
    	//freopen("1.in","r",stdin);
    	maxx=300;get(n);get(m);get(c);
    	rep(1,m,i)
    	{
    		int get(x),get(y);
    		add(x,y);add(y,x);
    	}
    	fac[0]=1;
    	rep(1,maxx,i)fac[i]=(ll)fac[i-1]*i%mod;
    	inv[maxx]=ksm(fac[maxx],mod-2);
    	fep(maxx-1,0,i)inv[i]=(ll)inv[i+1]*(i+1)%mod;
    	rep(1,n,i)if(!dfn[i])dfs(i);
    	ans=(ll)ans*ksm(c,cnt)%mod;
    	put(ans);return 0;
    }
    
  • 相关阅读:
    JS 位数不够自动左补0
    oracle 不同表空间的数据迁移
    Vue 学习
    c# 之Web.config
    c# 之泛型
    WritableWorkbook操作Excel
    MIME类型
    Excel 批量出来数据
    Excel的用到的常规的技巧
    得到Xml中 元素的值
  • 原文地址:https://www.cnblogs.com/chdy/p/13375505.html
Copyright © 2011-2022 走看看