zoukankan      html  css  js  c++  java
  • [loj6271]生成树求和

    将每一位拆开考虑,即不妨假设$0le c<3$

    考虑矩阵树定理,即统计所有生成树边权乘积的和,但我们这里要将边权相加,很明显将其作为幂次(如果作为$cx+1$无法对3取模)

    更具体的,也就是将每一个位置从1变为$x^{c}$,系数对$10^{9}+7$取模,相乘时幂次对3取模

    另外,高斯消元时需要对该多项式求逆,考虑$(ax^{2}+bx+c)^{-1}$即找到$dx^{2}+ex+f$满足
    $$
    (ax^{2}+bx+c)(dx^{2}+ex+f)equiv 1(mod x^{3}-1)
    $$
    (幂次对3取模等价于原多项式对$x^{3}-1$取模,关于这个正确性不证明也没关系,可以将这个对$x^{3}-1$看作一个符号)

    展开后,也就得到了如下的三元一次方程组
    $$
    egin{cases}ad+bf+ce=0\ ae+bd+cf=1\af+be+cd=0end{cases}
    $$
    通过一些计算,可以解得即
    $$
    egin{cases}d=frac{b^{2}-ac}{a^{3}+b^{3}+c^{3}-3abc}\e=frac{a^{2}-bc}{{a^{3}+b^{3}+c^{3}-3abc}}\f=frac{c^{2}-ab}{{a^{3}+b^{3}+c^{3}-3abc}}end{cases}
    $$
    根据$a^{3}+b^{3}+c^{3}-3abc=frac{(a+b+c)((a-b)^{2}+(b-c)^{2}+(c-a)^{2})}{2}$,若其为0其实与原来的0多项式是一样的,因此要判定要求$a e b$或$b e c$且$a+b+c e 0$($a+b+c otequiv 0(mod 10^{9}+7)$

    更特别的,在如果最后一个式子不满足上述条件,则还要乘上去

    由此计算即可,时间复杂度为$o(n^{3}log_{3}c)$

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 105
      4 #define mod 1000000007
      5 struct Edge{
      6     int x,y,z;
      7 }e[N*N];
      8 int n,m,ans;
      9 int pow(int n,int m){
     10     int s=n,ans=1;
     11     while (m){
     12         if (m&1)ans=1LL*ans*s%mod;
     13         s=1LL*s*s%mod;
     14         m>>=1;
     15     }
     16     return ans;
     17 }
     18 struct poly{
     19     int a[3];
     20     poly(){
     21         a[0]=a[1]=a[2]=0;
     22     }
     23     void init(){
     24         a[0]=a[1]=a[2]=0;
     25     }
     26     bool zero(){
     27         return (a[0]==a[1])&&(a[1]==a[2])||((0LL+a[0]+a[1]+a[2])%mod==0);
     28     }
     29     poly operator + (const poly &k)const{
     30         poly o;
     31         for(int i=0;i<3;i++)o.a[i]=(a[i]+k.a[i])%mod;
     32         return o;
     33     }
     34     poly operator - ()const{
     35         poly o;
     36         for(int i=0;i<3;i++)o.a[i]=(mod-a[i])%mod;
     37         return o;
     38     }
     39     poly operator * (const poly &k)const{
     40         poly o;
     41         for(int i=0;i<3;i++)
     42             for(int j=0;j<3;j++)o.a[(i+j)%3]=(o.a[(i+j)%3]+1LL*a[i]*k.a[j])%mod;
     43         return o;
     44     }
     45     poly inv(){
     46         int s=mod-3LL*a[0]*a[1]%mod*a[2]%mod;
     47         for(int i=0;i<3;i++)s=(s+1LL*a[i]*a[i]%mod*a[i])%mod;
     48         s=pow(s,mod-2);
     49         poly o;
     50         o.a[0]=(1LL*a[0]*a[0]-1LL*a[1]*a[2]%mod+mod)%mod*s%mod;
     51         o.a[1]=(1LL*a[2]*a[2]-1LL*a[0]*a[1]%mod+mod)%mod*s%mod;
     52         o.a[2]=(1LL*a[1]*a[1]-1LL*a[0]*a[2]%mod+mod)%mod*s%mod;
     53         return o;
     54     }
     55 }a[N][N];
     56 poly guess(){
     57     poly ans;
     58     ans.a[0]=1;
     59     for(int i=1;i<n;i++){
     60         int k=-1;
     61         for(int j=i;j<n;j++)
     62             if (!a[j][i].zero()){
     63                 k=j;
     64                 break;
     65             }
     66         if (k<0)return ans*a[i][i];
     67         if (k!=i){
     68             ans=(-ans);
     69             for(int j=i;j<n;j++)swap(a[i][j],a[k][j]);
     70         }
     71         ans=ans*a[i][i];
     72         for(int j=i+1;j<n;j++){
     73             poly o=a[j][i]*a[i][i].inv();
     74             for(int k=i;k<n;k++)a[j][k]=a[j][k]+(-o*a[i][k]);
     75         }
     76     }
     77     return ans;
     78 }
     79 int main(){
     80     freopen("sum.in","r",stdin);
     81     freopen("sum.out","w",stdout);
     82     scanf("%d%d",&n,&m);
     83     for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
     84     int s=1;
     85     while (1){
     86         bool flag=0;
     87         for(int i=1;i<n;i++)
     88             for(int j=1;j<n;j++)a[i][j].init();
     89         for(int i=1;i<=m;i++){
     90             poly o;
     91             o.a[e[i].z%3]=1;
     92             if (e[i].x<n)a[e[i].x][e[i].x]=a[e[i].x][e[i].x]+o;
     93             if (e[i].y<n)a[e[i].y][e[i].y]=a[e[i].y][e[i].y]+o;
     94             if ((e[i].x<n)&&(e[i].y<n)){
     95                 a[e[i].x][e[i].y]=a[e[i].x][e[i].y]+(-o);
     96                 a[e[i].y][e[i].x]=a[e[i].y][e[i].x]+(-o);
     97             }
     98             if (e[i].z)flag=1;
     99             e[i].z/=3;
    100         }
    101         if (!flag)break;
    102         poly o=guess();
    103         ans=(ans+1LL*s*o.a[1]+2LL*s*o.a[2])%mod;
    104         s=3LL*s%mod;
    105     }
    106     printf("%d",ans);
    107     return 0;
    108 } 
    View Code
  • 相关阅读:
    UVA 10976 Fractions Again?! 简单枚举题
    UVa 11059 Maximum Product(简单枚举7.1)使用longlong,输出格式%lld
    《Java核心技术卷I》——第5章 继承
    《Java核心技术卷I》——第3章 Java的基本程序设计结构
    windows服务器监控多个tomcat运行状态
    org.apache.jasper.JasperException: javax.el.PropertyNotFoundException: Property [xxx] not readable on type [xxx]
    断点续传
    创建密码带有特殊字符的dblink
    带有空格或tab的字符串的判断
    SQLState: 23000
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/14480953.html
Copyright © 2011-2022 走看看