[atARC062F]Painting Graphs with AtCoDeer
求出点双后缩点,对于点双之间,显然不存在简单环,即每一个简单环一定在一个点双内部,换言之即每一个点双可以独立的考虑,然后将结果相乘
(对于点双之间的边任意染色,即若有$s$条边,还会有$k^{s}$的贡献)
对点双分类讨论(假设其有$n$个节点,$m$条边):
1.$n=2$且$m=1$(也就是两点一边),贡献为$k$
2.$n=m$(一个环),根据polya定理,贡献即$\frac{\sum_{i=0}^{n-1}k^{\gcd(n,i)}}{n}$
3.$n<m$,则任意两边的颜色都可以单独交换(其他边的颜色不变),即仅关心每种颜色的边的数量,根据插板法,贡献即${m+k-1\choose k-1}$
关于第3类中任意两边的颜色可以单独交换,下面来证明一下:
更方便的,由于整个连通,那么原结论等价于可以单独交换有公共端点的两条边
简单分析,可以发现这两条边必然会属于一个简单环$R_{1}$,且$R_{1}$与另一个简单环$R_{2}$有公共边
先通过在$R_{1}$上轮换,使得其中恰好有一条边属于公共边的部分,另一条边仅属于$R_{1}$
接下来,将这两条边单独交换,然后再轮换返回原来的位置
具体来说,先轮换$R_{2}$使得原本在公共边上的边仅属于$R_{2}$,再轮换$R_{1}$使得原本在$R_{1}$中的边在公共边上,再轮换$R_{1}$和$R_{2}$除去公共边的部分,可以发现就完成了交换
(更形象地,可以参考atcoder题解中第3页的4幅图)
时间复杂度为$o(n+m)$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 55
4 #define mod 1000000007
5 struct Edge{
6 int nex,to;
7 }edge[N<<2];
8 stack<int>st;
9 vector<int>v[N];
10 int bcc,E,n,m,k,x,y,ans,head[N],dfn[N],low[N],vis[N];
11 int gcd(int x,int y){
12 if (!y)return x;
13 return gcd(y,x%y);
14 }
15 int pow(int n,int m){
16 int s=n,ans=1;
17 while (m){
18 if (m&1)ans=1LL*ans*s%mod;
19 s=1LL*s*s%mod;
20 m>>=1;
21 }
22 return ans;
23 }
24 void add(int x,int y){
25 edge[E].nex=head[x];
26 edge[E].to=y;
27 head[x]=E++;
28 }
29 void dfs(int k,int fa){
30 if (fa)st.push(k);
31 dfn[k]=low[k]=++dfn[0];
32 for(int i=head[k];i!=-1;i=edge[i].nex)
33 if (edge[i].to!=fa){
34 if (dfn[edge[i].to])low[k]=min(low[k],dfn[edge[i].to]);
35 else{
36 dfs(edge[i].to,k);
37 low[k]=min(low[k],low[edge[i].to]);
38 if (low[edge[i].to]>=dfn[k]){
39 while (1){
40 v[bcc].push_back(st.top());
41 st.pop();
42 if (v[bcc].back()==edge[i].to)break;
43 }
44 v[bcc++].push_back(k);
45 }
46 }
47 }
48 }
49 int main(){
50 scanf("%d%d%d",&n,&m,&k);
51 memset(head,-1,sizeof(head));
52 for(int i=1;i<=m;i++){
53 scanf("%d%d",&x,&y);
54 add(x,y);
55 add(y,x);
56 }
57 for(int i=1;i<=n;i++)
58 if (!dfn[i])dfs(i,0);
59 ans=1;
60 for(int i=0;i<bcc;i++){
61 int nn=v[i].size(),mm=0,s=0;
62 memset(vis,0,sizeof(vis));
63 for(int j=0;j<v[i].size();j++)vis[v[i][j]]=1;
64 for(int j=0;j<v[i].size();j++)
65 for(int k=head[v[i][j]];k!=-1;k=edge[k].nex)
66 if (vis[edge[k].to])mm++;
67 mm/=2;
68 if ((nn==2)&&(mm==1))s=k;
69 else{
70 if (nn==mm){
71 for(int j=0;j<nn;j++)s=(s+pow(k,gcd(nn,j)))%mod;
72 s=1LL*s*pow(nn,mod-2)%mod;
73 }
74 else{
75 s=1;
76 for(int j=mm+1;j<mm+k;j++)s=1LL*s*j%mod;
77 for(int j=1;j<k;j++)s=1LL*s*pow(j,mod-2)%mod;
78 }
79 }
80 ans=1LL*ans*s%mod;
81 }
82 printf("%d",ans);
83 }
[atARC062F]Painting Graphs with AtCoDeer的更多相关文章
- [Arc062] Painting Graphs with AtCoDeer
[Arc062] Painting Graphs with AtCoDeer Description 给定一张N点M边的无向图,每条边要染一个编号在1到K的颜色.你可以对一张染色了的图进行若干次操作, ...
- ARC 062 F - Painting Graphs with AtCoDeer 割点 割边 不动点 burnside引理
LINK:Painting Graphs with AtCoDeer 看英文题面果然有点吃不消 一些细节会被忽略掉. 问每条边都要被染色 且一个环上边的颜色可以旋转. 用c种颜色有多少本质不同的方法. ...
- AtcoderARC062F Painting Graphs with AtCoDeer 【双连通分量】【polya原理】
题目分析: 如果一个双连通分量是简单环,那么用polya原理计数循环移位即可. 如果一个双连通分量不是简单环,那么它必然可以两两互换,不信你可以证明一下相邻的可以互换. 如果一条边是桥,那么直接乘以k ...
- ARC062 - F. Painting Graphs with AtCoDeer (Polya+点双联通分量)
似乎好久都没写博客了....赶快来补一篇 题意 给你一个 \(n\) 个点 , 没有重边和自环的图 . 有 \(m\) 条边 , 每条边可以染 \(1 \to k\) 中的一种颜色 . 对于任意一个简 ...
- 2018.09.20 atcoder Painting Graphs with AtCoDeer(tarjan+polya)
传送门 一道思维题. 如果没有环那么对答案有k的贡献. 如果恰为一个环,可以用polya求贡献. 如果是一个有多个环重叠的双联通的话,直接转化为组合数问题(可以证明只要每种颜色被选取的次数相同一定可以 ...
- 【AtCoder】ARC062F - AtCoDeerくんとグラフ色塗り / Painting Graphs with AtCoDeer
题解 考虑一个点双(因为是简单环),如果没有环(两点一线),那么乘上K 如果有一个环,那么用polya定理,每个置换圈有gcd(i,n)个循环节 如果有两个及以上的环,任何一种置换都合法,那么只和每个 ...
- [ARC062F]Painting Graphs with AtCoDeer
题意:一个无向图,用$k$种不同的颜色给每条边染色,问能染出多少种不同的图,如果两张图能通过循环移位环边使得颜色相同,那么这两张图被认为是相同的 数学太差伤不起啊...补了一下Burnside定理的证 ...
- 【ARC062F】 Painting Graphs with AtCoDeer 点双连通分量+polya定理
Description 给定一张N点M边的无向图,每条边要染一个编号在1到K的颜色. 你可以对一张染色了的图进行若干次操作,每次操作形如,在图中选择一个简单环(即不经过相同点的环),并且将其颜色逆时针 ...
- ARC062F AtCoDeerくんとグラフ色塗り / Painting Graphs with AtCoDeer Burnside 引理
题目传送门 https://atcoder.jp/contests/arc062/tasks/arc062_d 题解 首先对整张图做 Tarjan 点双. 对于一个点双,如果是由一条边构成的,那么很显 ...
随机推荐
- 记录一次基于VuePress + Github 搭建个人博客
最终效果图 网站:https://chandler712.github.io/ 一.前言 VuePress 是尤雨溪推出的支持 Vue 及其子项目的文档需求而写的一个项目,UI简洁大方,官方文档详细容 ...
- 开启Nginx代理HTTPS功能
1.首先查看是否已经安装SSL openssl version -a 2.生成SSL证书 在nginx目录下创建ssl文件夹 cd /etc/pki mkdir nginx cd nginx 生成20 ...
- Schematics Tools(Schematics 工具)
Schematics工具 # Process: 创建逻辑示意图 arcpy.CreateDiagram_schematics("", "", "&qu ...
- 使用 PyTorch Lightning 将深度学习管道速度提高 10 倍
前言 本文介绍了如何使用 PyTorch Lightning 构建高效且快速的深度学习管道,主要包括有为什么优化深度学习管道很重要.使用 PyTorch Lightning 加快实验周期的六种 ...
- vue 动态菜单以及动态路由加载、刷新采的坑
需求: 从接口动态获取子菜单数据 动态加载 要求只有展开才加载子菜单数据 支持刷新,页面显示正常 思路: 一开始比较乱,思路很多.想了很多 首先路由和菜单共用一个全局route, 数据的传递也是通过s ...
- 题解 GRE Words Revenge
题目传送门 题目大意 给出 \(m\) 次操作,分别为以下两种操作: 学习一个单词 给出一个段落,查询里面有多少个学过的单词.注意,如果学习过 \(\text{ab,bc}\) ,当前查询段落为 \( ...
- FastAPI 学习之路(十二)接口几个额外信息和额外数据类型
系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...
- Arp欺骗和DNS投毒的实验性分析
1.中间人攻击之Arp欺骗/毒化 本文涉及网络安全攻击知识,随时可能被永久删除.请Star我的GitHub仓库 实现原理: 这种攻击手段也叫做中间人攻击MITM(Man-in-the-Middle) ...
- Java:反射小记
Java:反射小记 对 Java 中的 反射,做一个微不足道的小小小小记 概念 Java 反射指的是在 Java 程序运行状态中,对于任何一个类,都可以获得这个类的所有属性和方法:对于给定的一个对象, ...
- 2021.10.7 NKOJ周赛总结
Ⅰ. 自描述序列 问题描述: 序列 1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1,... 看似毫无规律,但若我们将相邻的数字合并 : 1,22,11,2,1,22,1 ...