(以下假设$T=(V,\{e_{1},e_{2},...,e_{n-1} \})$是一棵树)
根据莫比乌斯反演,有$\gcd(w_{1},w_{2},...,w_{e_{n-1}})=\sum_{d|w_{e_{i}}}\varphi(d)$
容易想到枚举$d$,之后相当于求$\sum_{d}\varphi(d)\sum_{d|w_{e_{i}}}\sum_{i=1}^{n-1} w_{e_{i}}$
那么即找出所有权值为$d$的倍数的边,然后求所有生成树的边权和的和,但矩阵树定理只能求边权积之和(将邻接矩阵权值改为边权,将度数矩阵的度数改为出边的边权和,即【bzoj3534】)
考虑令边i的边权为$1+w_{i}x$,那么容易发现所有边权乘积的和的1次项系数即为答案
同时多项式只需要维护0次项和1次项(即模$x^{2}$意义下运算),因此复杂度为$o(dn^{3})$,仍然无法通过
考虑一个优化:如果$d$的倍数的边小于$n-1$条,显然无解;那么最坏的构造方式为:选出n组边,每组n条边边权相同,那么最多有有$2\sqrt{d}n$种合法的d,复杂度降为$o(\sqrt{d}n^{4})$,且其中会产生许多重复边权,并不会跑满
还有一件事情,这样的高斯消元会有很多细节:
1.多项式除法,由于在模$x^{2}$意义下,所以直接手动解方程推出$(ax+b)^{-1}\equiv \frac{1}{b}-\frac{a}{b^{2}}x(mod\ x^{2})$
2.若存在常数项非0,将该点与当前行交换;若不存在,那么直接用一次项系数消除(因为常数项都为0),即$inv(ax)=a^{-1}$

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 35
4 #define D 152501
5 #define mod 998244353
6 #define mp make_pair
7 #define pii pair<int,int>
8 #define fi first
9 #define se second
10 struct ji{
11 int nex,to,len;
12 }edge[N*N];
13 int E,n,m,x,y,z,ans,head[N],p[D+10],phi[D+10];
14 pii d[N][N];
15 int ksm(int n,int m){
16 if (!m)return 1;
17 int s=ksm(n,m>>1);
18 s=1LL*s*s%mod;
19 if (m&1)s=1LL*s*n%mod;
20 return s;
21 }
22 pii add(pii x,pii y){
23 return mp((x.fi+y.fi)%mod,(x.se+y.se)%mod);
24 }
25 pii mul(pii x,pii y){
26 return mp(1LL*x.fi*y.fi%mod,(1LL*x.fi*y.se+1LL*x.se*y.fi)%mod);
27 }
28 pii inv(pii x){
29 if (!x.fi)return mp(ksm(x.se,mod-2),0);
30 int s=ksm(x.fi,mod-2);
31 return mp(s,mod-1LL*x.se*s%mod*s%mod);
32 }
33 void add(int x,int y,int z){
34 edge[E].nex=head[x];
35 edge[E].to=y;
36 edge[E].len=z;
37 head[x]=E++;
38 }
39 int find1(int k){
40 for(int i=k;i<n;i++)
41 if (d[i][k].fi)return i;
42 return 0;
43 }
44 int find2(int k){
45 for(int i=k;i<n;i++)
46 if (d[i][k].se)return i;
47 return 0;
48 }
49 int main(){
50 phi[1]=1;
51 for(int i=2;i<=D;i++){
52 if (!phi[i]){
53 p[++p[0]]=i;
54 phi[i]=i-1;
55 }
56 for(int j=1;(j<=p[0])&&(i*p[j]<=D);j++){
57 if (i%p[j])phi[i*p[j]]=phi[i]*phi[p[j]];
58 else{
59 phi[i*p[j]]=phi[i]*p[j];
60 break;
61 }
62 }
63 }
64 scanf("%d%d",&n,&m);
65 memset(head,-1,sizeof(head));
66 for(int i=1;i<=m;i++){
67 scanf("%d%d%d",&x,&y,&z);
68 add(x,y,z);
69 add(y,x,z);
70 }
71 for(int i=1;i<=D;i++){
72 x=0;
73 for(int j=0;j<E;j+=2)
74 if (edge[j].len%i==0)x++;
75 if (x<n-1)continue;
76 memset(d,0,sizeof(d));
77 for(int j=1;j<n;j++)
78 for(int k=head[j];k!=-1;k=edge[k].nex)
79 if (edge[k].len%i==0){
80 d[j][j]=add(d[j][j],mp(1,edge[k].len));
81 if (edge[k].to<n)d[j][edge[k].to]=mp(mod-1,mod-edge[k].len);
82 }
83 pii s=mp(1,0);
84 for(int j=1;j<n;j++){
85 x=find1(j);
86 if (!x)y=find2(j);
87 if (!x){
88 s.se=0;
89 break;
90 }
91 if (x!=j){
92 s=mp(mod-s.fi,mod-s.se);
93 for(int k=j;k<n;k++)swap(d[j][k],d[x][k]);
94 }
95 s=mul(s,d[j][j]);
96 pii t=inv(d[j][j]);
97 for(int k=j;k<n;k++)d[j][k]=mul(d[j][k],t);
98 for(int k=j+1;k<n;k++){
99 t=mp(mod-d[k][j].fi,mod-d[k][j].se);
100 for(int l=j;l<n;l++)d[k][l]=add(d[k][l],mul(t,d[j][l]));
101 }
102 }
103 ans=(ans+1LL*s.se*phi[i])%mod;
104 }
105 printf("%d",ans);
106 }

[loj3304]作业题的更多相关文章

  1. nyoj201 作业题

    作业题 时间限制: 3000 ms  |  内存限制: 65535 KB 难度: 3   描述 小白同学这学期有一门课程叫做<数值计算方法>,这是一门有效使用数字计算机求数学问题近似解的方 ...

  2. NYOJ201作业题

    作业题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 小白同学这学期有一门课程叫做<数值计算方法>,这是一门有效使用数字计算机求数学问题近似解的方法与过程, ...

  3. [ python ] 字符串的操作及作业题

    字符串的操作方法 capitalize() : 首字母大写 s1 = 'my heart will go on' print(s1.capitalize()) # 首字母大写 # 执行结果: # My ...

  4. nyoj 作业题 dp

    作业题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 小白同学这学期有一门课程叫做<数值计算方法>,这是一门有效使用数字计算机求数学问题近似解的方法与过程, ...

  5. NYOJ 201 作业题

    作业题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 小白同学这学期有一门课程叫做<数值计算方法>,这是一门有效使用数字计算机求数学问题近似解的方法与过 ...

  6. 作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)

    作业题:闰年 if((year%4==0&&year%100!=0)||year&400==0)

  7. python27期day14:有参装饰器、多个装饰器装饰一个函数、递归、作业题

    1.有参装饰器:给装饰器添加一个参数.来控制装饰器的行为. @auth(参数) auth里层的函数名 = auth(参数) 被装饰的函数名 = auth里层的函数名(被装饰的函数名) 被装饰的函数名( ...

  8. python27期day13:闭包、装饰器初始、标准版装饰器、作业题

    1.闭包: 保护数据安全.保护数据干净性. 2.闭包的定义:在嵌套函数内.使用非全局变量(且不使用本层变量) 将嵌套函数返回 闭包的目的:要接受被装饰的函数和被装饰函数需要的参数3.闭包举例子: de ...

  9. python27期day12:推导式、内置函数、高阶函数、匿名函数、作业题

    1.推导式:做一些有规律的数据结构 列表推导式: 普通循环模式: [加工后的变量 for 循环] 示例一:print([i for i in range(1,51)]) 结果:[1, 2, 3, 4, ...

随机推荐

  1. WPF之资源专题

    1.一般程序的资源可以分为四个等级: 数据库中的数据相当于放在仓库里 资源文件里的数据相当于放在旅行箱里 WPF对象资源里的数据相当于携带在背包里 变量中的数据相当于拿在手里 2.资源的查找顺序是沿着 ...

  2. java课堂测试3第一部分(未完善)

    package test3;import java.util.*; public class Grade2 { static String[][] mis=new String[500][4]; // ...

  3. Java初步学习——2021.10.11每日总结,第六周周一

    (1)今天做了什么: (2)明天准备做什么? (3)遇到的问题,如何解决? 今天继续学习菜鸟教程Java实例 字符串 9.字符串小写转大写--toUpperCase方法 public class Ma ...

  4. 使用CSS选择器(第二部分)

    伪类跟伪元素一样,并不是直接针对文档元素的,而是为你基于某些共同特征选择元素提供方便. 使用结构性伪类选择器 使用结构性伪类选择器能够根据元素在文档中的位置选择元素.这类选择器都有一个冒号字符前缀(: ...

  5. java实现责任链模式的小demo

    //一个请假请求 public class LeaveRequest { private int leaveDays; private String name; public void leave() ...

  6. NX9.0和NX10.0做自定义操作可以用的函数

    NX9.0:LIBUFUNX.DLL int UF_OPER_ask_check_geom(void *,int *,unsigned int * *) int UF_OPER_ask_first_o ...

  7. (课内)信安数基RSA-level1&&2

    注:(不求甚解的)攻击原理 以及(浅层的)算法解释已在图片中给出:文字部分主要讲一些python语法的东西. 代码需要库 gmpy2和libnum:加密算法还需要Crypto.Util.number ...

  8. Java继承中父类和子类构造函数的问题

    父类有无参构造函数时(显示或隐式),子类的有参和无参构造函数都是默认调用父类的无参构造函数:当父类只有有参构造函数时,子类可以有有参和无参构造函数,子类有参构造函数必须显式调用父类的有参构造函数,子类 ...

  9. 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她

    原文链接: 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她 上篇文章 gRPC,爆赞 直接爆了,内容主要包括:简单的 gRPC 服务,流处理模式,验证器,Token 认证和证书认证. 在多 ...

  10. 新產品SWOT分析實例

    推出新产品需要解决四个行销支柱: 价格 产品 促销 销售地点 要分析这些方面,请检查您的优势.劣势.机会和威胁,以帮助您在运行第一个广告或举行第一次促销之前将风险降至最低,并最大限度地利用资源.SWO ...