AtcoderARC062F Painting Graphs with AtCoDeer 【双连通分量】【polya原理】
题目分析:
如果一个双连通分量是简单环,那么用polya原理计数循环移位即可。
如果一个双连通分量不是简单环,那么它必然可以两两互换,不信你可以证明一下相邻的可以互换。
如果一条边是桥,那么直接乘以k就行了。
代码:
#include<bits/stdc++.h>
using namespace std; const int mod = ;
const int maxn = ; int n,m,k;
vector <int> g[maxn]; int fa[maxn],arr[maxn],dfn[maxn],bccnum,low[maxn],cl; vector <pair<int,int> > bcc[maxn];
vector <int> hhh[maxn]; void read(){
scanf("%d%d%d",&n,&m,&k);
for(register int i=;i<=m;i++){
int u,v; scanf("%d%d",&u,&v);
g[u].push_back(v); g[v].push_back(u);
}
} stack<int> sta;
void Tarjan(int now,int f){
fa[now] = f;
low[now] = dfn[now] = ++cl;
sta.push(now);
for(int i=;i<g[now].size();i++){
if(g[now][i] == f) continue;
if(dfn[g[now][i]] > dfn[now]) continue;
if(!dfn[g[now][i]]){
Tarjan(g[now][i],now);
low[now] = min(low[now],low[g[now][i]]);
}else{
low[now] = min(low[now],dfn[g[now][i]]);
hhh[now].push_back(g[now][i]);
}
}
if(f == || low[now] >= dfn[fa[now]]){
bccnum++;
while(true){
int k = sta.top();sta.pop();
arr[k] = ;
if(fa[k] == ) break;
bcc[bccnum].push_back(make_pair(k,fa[k]));
for(int i=;i<hhh[k].size();i++){
bcc[bccnum].push_back(make_pair(k,hhh[k][i]));
}
if(k == now) break;
}
if(bcc[bccnum].size() == ) bccnum--;
}
} int C[maxn*][maxn*]; int fast_pow(int now,int pw){
int ans = ,dt = now, bit = ;
while(bit <= pw){
if(bit & pw){ans =1ll*ans*dt%mod;}
dt = 1ll*dt*dt%mod; bit<<=;
}
return ans;
} int solve(int now){
int ans = ;
for(register int i=;i<=now;i++){
ans += fast_pow(k,__gcd(now,i));
ans %= mod;
}
ans = 1ll*ans*fast_pow(now,mod-)%mod;
return ans;
} int hap[maxn];
void work(){
for(register int i=;i<=n;i++){
if(arr[i]) continue;
Tarjan(i,);
}
C[][] = ;
for(register int i=;i<=;i++){
C[i][] = C[i][i] = ;
for(register int j=;j<i;j++){
C[i][j] = (C[i-][j] + C[i-][j-])%mod;
}
}
int ans = ;
for(register int i=;i<=bccnum;i++){
int flag = ;
for(register int j=;j<bcc[i].size();j++){
if(hap[bcc[i][j].first] && hap[bcc[i][j].second]) flag--;
hap[bcc[i][j].first]++; hap[bcc[i][j].second]++;
}
for(register int j=;j<bcc[i].size();j++){
hap[bcc[i][j].first]--; hap[bcc[i][j].second]--;
}
if(flag == || flag == ){
if(bcc[i].size() == ) ans = 1ll*ans*k%mod;
else ans = 1ll*ans*solve(bcc[i].size())%mod;
}else{
ans = 1ll*ans*C[bcc[i].size()+k-][k-]%mod;
}
}
printf("%d",ans);
} int main(){
read();
work();
return ;
}
AtcoderARC062F Painting Graphs with AtCoDeer 【双连通分量】【polya原理】的更多相关文章
- 2018.09.20 atcoder Painting Graphs with AtCoDeer(tarjan+polya)
传送门 一道思维题. 如果没有环那么对答案有k的贡献. 如果恰为一个环,可以用polya求贡献. 如果是一个有多个环重叠的双联通的话,直接转化为组合数问题(可以证明只要每种颜色被选取的次数相同一定可以 ...
- [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种颜色有多少本质不同的方法. ...
- HohoCoder 1184 : 连通性二·边的双连通分量(+原理证明)
1184 : 连通性二·边的双连通分量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老师 ...
- 【ARC062F】 Painting Graphs with AtCoDeer 点双连通分量+polya定理
Description 给定一张N点M边的无向图,每条边要染一个编号在1到K的颜色. 你可以对一张染色了的图进行若干次操作,每次操作形如,在图中选择一个简单环(即不经过相同点的环),并且将其颜色逆时针 ...
- ARC062 - F. Painting Graphs with AtCoDeer (Polya+点双联通分量)
似乎好久都没写博客了....赶快来补一篇 题意 给你一个 \(n\) 个点 , 没有重边和自环的图 . 有 \(m\) 条边 , 每条边可以染 \(1 \to k\) 中的一种颜色 . 对于任意一个简 ...
- 【AtCoder】ARC062F - AtCoDeerくんとグラフ色塗り / Painting Graphs with AtCoDeer
题解 考虑一个点双(因为是简单环),如果没有环(两点一线),那么乘上K 如果有一个环,那么用polya定理,每个置换圈有gcd(i,n)个循环节 如果有两个及以上的环,任何一种置换都合法,那么只和每个 ...
- [atARC062F]Painting Graphs with AtCoDeer
求出点双后缩点,对于点双之间,显然不存在简单环,即每一个简单环一定在一个点双内部,换言之即每一个点双可以独立的考虑,然后将结果相乘 (对于点双之间的边任意染色,即若有$s$条边,还会有$k^{s}$的 ...
- [ARC062F]Painting Graphs with AtCoDeer
题意:一个无向图,用$k$种不同的颜色给每条边染色,问能染出多少种不同的图,如果两张图能通过循环移位环边使得颜色相同,那么这两张图被认为是相同的 数学太差伤不起啊...补了一下Burnside定理的证 ...
随机推荐
- eclipse 执行自带的maven命令无效
原文地址:https://blog.csdn.net/qq_26386171/article/details/78262702 下面加上(前提是你的环境变量里已经配置过) -Dmaven.multiM ...
- c++入门之—运算符重载和友元函数
运算符重载的意义是:将常见的运算符重载出其他的含义:比如将*重载出指针的含义,将<<与cout联合使用重载出输出的含义,但需要认识到的问题是:运算符的重载:本质仍然是成员函数,即你可以认为 ...
- 【M2】软件工程终期总结报告——前端设计总结
PhylabWeb——前端设计感想 简介 本文的内容是关于我参与的软件工程项目——“Phylab-Web物理实验中心网站”的前端设计个人总结,来自团队:软剑攻城队 网站地址为:http://buaap ...
- 日志之环绕通知(AOP)
环绕通知:一个完整的try...catch...finally结构 编写环绕通知方法,环绕通知需要携带ProceedingJoinPoint 这个类型的参数,ProceedingJoinPoint类型 ...
- 《梦断代码》Scott Rosenberg著(三)
开放与封闭之论: 程序源代码是商业软件公司最重要的资产,所以软件公司售卖二进制文件.这样也就意味着如果微软的软件产品出了问题,即便你是一个程序大牛也无法修复它.你只能等着微软来修正问题,因为只有微软程 ...
- 【转】shell之for、while、until循环
一.简介 Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for.while和until.while循环和for循环属于“当型循环”,而unti ...
- 【学习总结】Git学习-参考廖雪峰老师教程-期末总结
学习总结之Git学习-总 目录: 一.Git简介 二.安装Git 三.创建版本库 四.时光机穿梭 五.远程仓库 六.分支管理 七.标签管理 八.使用GitHub 九.使用码云 十.自定义Git 期末总 ...
- js数据放入缓存,需要再调用
再贴代码之前先描述下,这个技术应用的场景:一个页面的http请求次数能少点就少,这样大大提高用户体验.所以再一个页面发起一个请求,把所有数据都拿到后储存在缓存里面,你想用的时候再调用出来,这个是非常好 ...
- array_filter与array_map
php数组array_filter函数和array_slice函数:<?php /* array_filter()用回调函数过滤数组中的单元 array_filter(array,functio ...
- Azure系列2.1.1 —— BlobContainerPermissions
(小弟自学Azure,文中有不正确之处,请路过各位大神指正.) 网上azure的资料较少,尤其是API,全是英文的,中文资料更是少之又少.这次由于公司项目需要使用Azure,所以对Azure的一些学习 ...