又是一个矩阵树套多项式的好题。

这里我们可以对每一位单独做矩阵树,但是矩阵树求的是边权积的和,而这里我们是要求加法,于是我们i将加法转化为多项式的乘法,其实这里相当于一个生成函数?之后如果我们暴力做的话,就是强行带入x插值,复杂度$O(8*2n*n^{3})$,还不够优秀,于是我们考虑用$dft$优化这个过程,这里我们需要找到一个三次单位根,于是我们考虑扩域的思想,我们把数表示为$(a+b*w_{3})$,这里$w_{3}$满足$w_{3}^{3}=1$且$w_{3}^{1}+w_{3}^{2}+w_{3}^{3}=0$,于是我们可以计算出这类数的计算法则,然后我们直接将矩阵dft之后做一遍矩阵树,之后再将答案逆变换回去,就是我们需要的答案了。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define N 111
#define mod 1000000007
#define inv3 333333336
using namespace std;
int qp(int a,int b){
int c=;
for(;b;b>>=,a=1ll*a*a%mod)
if(b&)c=1ll*c*a%mod;
return c;
}
struct num{
int a,b;
num(){}
num(int x,int y){a=x;b=y;}
num operator + (num x){return num((a+x.a)%mod,(b+x.b)%mod);}
num operator - (num x){return num((a-x.a+mod)%mod,(b-x.b+mod)%mod);}
num operator * (num x){
return num(
((1ll*a*x.a-1ll*b*x.b)%mod+mod)%mod,
((1ll*a*x.b+1ll*b*x.a-1ll*b*x.b)%mod+mod)%mod);
}
num inv(){
int val=qp(((1ll*a*b-1ll*a*a-1ll*b*b)%mod+mod)%mod,mod-);
return num(1ll*(b-a+mod)*val%mod,1ll*b*val%mod);
}
bool operator ! (){return !a&&!b;}
}A[N][N][],w[],det[];
int n,m,ans,du[N*N],dv[N*N],dw[N*N];
int cnt;
void work(){
num t;
for(int d=;d<=;d++){
det[d]=num(,);
for(int k=;k<n;k++){
if(!A[k][k][d]){
for(int i=k+;i<=n;i++){
if(!(!A[i][k][d])){
det[d]=num(,)-det[d];
for(int j=k;j<=n;j++)swap(A[k][j][d],A[i][j][d]);
break;
}
}
if(!A[k][k][d]){det[d]=num(,);break;}
}
det[d]=det[d]*A[k][k][d];
for(int i=k+;i<n;i++){
t=A[i][k][d]*A[k][k][d].inv();
for(int j=k;j<=n;j++)
A[i][j][d]=A[i][j][d]-t*A[k][j][d];
}
}
}
}
void dft(num *a){
num b[];
b[]=a[]+a[]+a[];
b[]=a[]+a[]*w[]+a[]*w[];
b[]=a[]+a[]*w[]+a[]*w[];
a[]=b[];a[]=b[];a[]=b[];
}
void add(int u,int v,int w){
A[u][u][w]=A[u][u][w]+num(,);
A[v][v][w]=A[v][v][w]+num(,);
A[u][v][w]=A[u][v][w]-num(,);
A[v][u][w]=A[v][u][w]-num(,);
}
void UPD(int &a,int b){
a=(a+b>=mod)?(a+b-mod):(a+b);
}
int main(){
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
w[]=num(,);w[]=num(,);
w[]=num(mod-,mod-);
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d%d%d",&du[i],&dv[i],&dw[i]);
for(int t=,now=;t<=;t++,now=now*){
memset(A,,sizeof A);
for(int i=;i<=m;i++){
add(du[i],dv[i],dw[i]%);
dw[i]/=;
}
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
dft(A[i][j]);
cnt=t;
work();
swap(w[],w[]);
dft(det);
swap(w[],w[]);
UPD(ans,1ll*det[].a*inv3%mod*now%mod);
UPD(ans,1ll*det[].a*inv3%mod**now%mod);
}
printf("%d\n",ans);
return ;
}

loj6271「长乐集训 2017 Day10」生成树求和 加强版的更多相关文章

  1. loj6271 「长乐集训 2017 Day10」生成树求和 加强版(矩阵树定理,循环卷积)

    loj6271 「长乐集训 2017 Day10」生成树求和 加强版(矩阵树定理,循环卷积) loj 题解时间 首先想到先分开三进制下每一位,然后每一位分别求结果为0,1,2的树的个数. 然后考虑矩阵 ...

  2. LOJ#6271. 「长乐集训 2017 Day10」生成树求和 加强版

    传送门 由于是边权三进制不进位的相加,那么可以考虑每一位的贡献 对于每一位,生成树的边权相当于是做模 \(3\) 意义下的加法 考虑最后每一种边权的生成树个数,这个可以直接用生成函数,在矩阵树求解的时 ...

  3. 「长乐集训 2017 Day10」划分序列 (二分 dp)

    「长乐集训 2017 Day10」划分序列 题目描述 给定一个长度为 n nn 的序列 Ai A_iA​i​​,现在要求把这个序列分成恰好 K KK 段,(每一段是一个连续子序列,且每个元素恰好属于一 ...

  4. 「长乐集训 2017 Day8」修路 (斯坦纳树)

    题目描述 村子间的小路年久失修,为了保障村子之间的往来,AAA君决定带领大家修路. 村子可以看做是一个边带权的无向图GGG, GGG 由 nnn 个点与 mmm 条边组成,图中的点从 1∼n1 \si ...

  5. 「长乐集训 2017 Day1」区间 线段树

    题目 对于两个区间\((a,b),(c,d)\),若\(c < a < d\)或\(c < b < d\)则可以从\((a,b)\)走到\((c,d)\)去,现在有以下两种操作 ...

  6. 「6月雅礼集训 2017 Day10」quote

    [题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. ...

  7. LOJ#6049. 「雅礼集训 2017 Day10」拍苍蝇(计算几何+bitset)

    题面 传送门 题解 首先可以用一个矩形去套这个多边形,那么我们只要枚举这个矩形的左下角就可以枚举完所有多边形的位置了 我们先对每一个\(x\)坐标开一个\(bitset\),表示这个\(x\)坐标里哪 ...

  8. LOJ#6047. 「雅礼集训 2017 Day10」决斗(set)

    题面 传送门 题解 这么简单一道题我考试的时候居然只打了\(40\)分暴力? 如果我们把每个点的\(a_i\)记为\(deg_i-1\),其中\(deg_i\)表示有\(deg_i\)个数的\(A_i ...

  9. LOJ#6048. 「雅礼集训 2017 Day10」数列(线段树)

    题面 传送门 题解 我的做法似乎非常复杂啊-- 首先最长上升子序列长度就等于把它反过来再接到前面求一遍,比方说把\(2134\)变成\(43122134\),实际上变化之后的求一个最长上升子序列和方案 ...

随机推荐

  1. css3-------:before和:after的作用

    1.:before和:after的作用就是在指定的元素内容(而不是元素本身)之前或者之后插入一个包含content属性指定内容的行内元素,最基本的用法如下: <!doctype html> ...

  2. go 实现struct转map

    从python转golang大约一个月了,对struct的使用还算顺手,但是很多时候还是会想念python的便捷.比如同时遍历两个字典,python使用for (x, y) in zip(map1, ...

  3. JBOSS的启动和停止

    本实例使用的JBOSS版本是jboss-4.2.3.GA 假设条件 1.  已设置好JAVA_HOME环境变量 2.  已下载JBoss并且安装目录为:D:\Java\jboss-4.2.3.GA 启 ...

  4. 【转载】Linux Cache Mechanism Summary(undone)

    http://www.cnblogs.com/LittleHann/p/3904909.html 目录 1. 缓存机制简介 2. 内核缓存机制 3. 内存缓存机制 4. 文件缓存机制 5. 数据库缓存 ...

  5. vi 常用命令使用說明

    vi是一種文字模式全螢幕文字編輯軟體(Text Editor).對初學者來說,vi是個很難用的工具,一般需要2個星期的時間才能得心應手.之所以介紹vi,其理由如下: vi是Unix上的標準文字編輯軟體 ...

  6. wxpython实现界面跳转

    wxPython实现Frame之间的跳转/更新的一种方法 wxPython是Python中重要的GUI框架,下面通过自己的方法实现模拟类似PC版微信登录,并跳转到主界面(朋友圈)的流程. (一)项目目 ...

  7. java之Spring(AOP)前奏-动态代理设计模式(下)

    在上一章我们看到了,新增的三种类都能实现对原始功能类进行添加功能的事务处理,这三种类就是一个代理. 但是这种代理是写死的,怎样实现对任意接口添加自定义的代理呢? 我们先来看一下之前的代理实现: pub ...

  8. SOFA 源码分析 — 泛化调用

    前言 通常 RPC 调用需要客户端使用服务端提供的接口,而具体的形式则是使用 jar 包,通过引用 jar 包获取接口的的具体信息,例如接口名称,方法名称,参数类型,返回值类型. 但也存在一些情况,例 ...

  9. SOFA 源码分析 —— 服务发布过程

    前言 SOFA 包含了 RPC 框架,底层通信框架是 bolt ,基于 Netty 4,今天将通过 SOFA-RPC 源码中的例子,看看他是如何发布一个服务的. 示例代码 下面的代码在 com.ali ...

  10. AE、AS调用时用代码提供许可(不需要添加LicenseControl控件)

    private void CheckBindLicense() { ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDe ...