• [校内训练20_01_21]ABC


    1.西瓜恒等式

    $$sum_{P.is.a.permutation}{frac{1}{A[P[1]]×(A[P[1]]+A[P[2]])×...×(A[P[1]]+...+A[P[n]])}}=frac{1}{A[1]×A[2]×...×A[n]}$$


     2.西瓜定理

    对于任意am+4≡a(mod m),有:


    3.给一个无向图,你需要给边染色(k种颜色),在允许将一个简单环经行旋转的情况下,问本质不同的图的数量。

      答案显然对于每一个点双连通分量是独立的,对于每一个点双连通分量,我们把它们的贡献乘起来,而不在点双上的一条边,有 k 种染色方法,所有贡献乘起来即可。
      对于树的情况,每个点双连通分量只有一个点,答案显然为 km
      对于环的情况,若一个点双连通分量只有一个点,则没有贡献,其他情况一个点双连通分量就是一个环,对于一个环只有循环左移操作,用 polya 定理求答案即可。
      剩下的情况一个点双中至少存在两个有相交部分的环,我们考虑先分别把两个小环顺时针操作,再把两个小环所在的大环逆时针操作,这样三步之后其余位置都不变,只有相邻两个交换了位置,因为我们可以交换特定位置上的两个且可以循环左移,我们就可以任意排列这些元素,即在一个至少有两个环的点双上,两个方案只要每种颜色出现次数相同,我们就能把它们变得一样。方案数为C(m+k-1,k-1)。(画图理解)
      把以上三种贡献乘起来即可。
     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 
     4 using namespace std;
     5 
     6 const int N=55,M=205,P=1e9+7;
     7 typedef long long ll;
     8 
     9 vector<int>e[N];
    10 int dfn[N],low[N],dfc,st[N],tp,fac[M],ifac[M];
    11 int n,m,k,ans=1;
    12 set<int>dat;
    13 
    14 int fpow(int a,int t){static int r;for(r=1;t;t>>=1,a=(ll)a*a%P)if(t&1)r=(ll)r*a%P;return r;}
    15 int C(int n,int m){return (ll)fac[n]*ifac[m]%P*ifac[n-m]%P;}
    16 int gcd(int x,int y){return y?gcd(y,x%y):x;}
    17 int polya(int n){int r=0;for(int i=1;i<=n;i++)r=(r+fpow(k,gcd(n,i)))%P;return (ll)r*fpow(n,P-2)%P;}
    18 int permu(int m){return C(m+k-1,k-1);}
    19 
    20 void tarjan(int x,int fa){
    21     dfn[x]=low[x]=++dfc,st[++tp]=x;
    22     for(int v:e[x])if(v!=fa){
    23         if(!dfn[v]){
    24             tarjan(v,x),low[x]=min(low[x],low[v]);
    25             if(low[v]>=dfn[x]){
    26                 dat.clear();
    27                 int n=0,m=0,las;
    28                 do dat.insert(st[tp]),las=st[tp],st[tp--]=0,n++;while(las!=v);
    29                 dat.insert(x),n++;
    30                 for(int u:dat)for(int v:e[u])if(dat.count(v))m++;m>>=1;
    31                 if(m<n)ans=(ll)ans*k%P;
    32                 else if(m==n)ans=(ll)ans*polya(n)%P;
    33                 else ans=(ll)ans*permu(m)%P;
    34             }
    35         }else low[x]=min(low[x],dfn[v]);
    36     }
    37     if(fa==0)st[tp--]=0;
    38 }
    39 
    40 int main(){
    41     freopen("graph.in","r",stdin);
    42     freopen("graph.out","w",stdout);
    43     scanf("%d%d%d",&n,&m,&k);
    44     fac[0]=1;
    45     for(int i=1;i<=m+k;i++)fac[i]=(ll)fac[i-1]*i%P;
    46     ifac[m+k]=fpow(fac[m+k],P-2);
    47     for(int i=m+k;i>=1;i--)ifac[i-1]=(ll)ifac[i]*i%P;
    48     for(int i=1,u,v;i<=m;i++)scanf("%d%d",&u,&v),e[u].pb(v),e[v].pb(u);
    49     for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i,0);
    50     printf("%d
    ",ans);
    51     return 0;
    52 }
    View Code
  • 相关阅读:
    软件研发:公司内部技术考试——算法编程题程序框架
    软件研发:公司内部技术考试——答题方法
    JConsole & JVisualVM远程监视Websphere服务器JVM的配置方法
    java.sql.SQLException: ORA-01578: ORACLE 数据块损坏问题解决办法
    ORA-00001: unique constraint (...) violated并不一定是数据冲突
    Linux部署Web应用程序超链接下载中文名称文件404问题解决办法
    Windows平台使用RMAN命令自动删除Oracle过期归档日志的方法
    Oracle调整内存超出限制出现ORA-27100: shared memory realm already exists问题解决办法
    linux下查看最消耗CPU、内存的进程
    RMAN正确地删除Archivelog以及设置有备库的归档删除策略
  • 原文地址:https://www.cnblogs.com/GreenDuck/p/12252863.html
Copyright © 2020-2023  润新知