传送门

直接的想法就是设 \(x^k\) 为边权,矩阵树定理一波后取出 \(x^{nk}\) 的系数即可

也就是求出模 \(x^k\) 意义下的循环卷积的常数项

考虑插值出最后多项式,类比 \(DFT\) 的方法

假设我们要求

\[C_i=\sum_{j=0}^{n}\sum_{k=0}^{n}A_jB_k[(j+k)~mod~n=i]
\]

\(A,B,C\) 为多项式

我们知道了 \(A,B\) 的 \(n\) 个点值

\[A(w_n^i)=\sum_{k=0}^{n}A_kw_n^{ik}
\]

\[B(w_n^i)=\sum_{k=0}^{n}B_kw_n^{ik}
\]

那么

\[C(w_n^k)=\sum_{i=0}^{n}\sum_{j=0}^{n}A_iw_n^{ik}B_jw_n^{jk}=\sum_{i=0}^{n}\sum_{j=0}^{n}A_iB_jw_n^{k(i+j)}
\]

而根据消去引理 \(w_n^{k(i+j)}=w_n^{k((i+j)~mod~n)}\)

所以

\[C(w_n^k)=\sum_{l=0}^{n}\sum_{i=0}^{n}\sum_{j=0}^{n}[(i+j)~mod~n=l]A_iB_jw_n^{kl}
\]

正好对应了循环卷积,所以只要求得到 \(w_n^{k},(k=0...n-1)\) 的点值就可以得到最后的多项式了

这道题 \(p~mod~k=1\) 所以直接用原根就好了,最后插值一下

upd: 其实最后并不需要插值

根据单位根反演

\[[k|x]=\frac{1}{k}\sum_{i=0}^{k-1}\omega_{k}^{ix}
\]

把多项式的每一项都换成这个东西,得到的值就是要的答案

也就是说直接带入每一个单位根,把矩阵树定理得到的权值加起来最后除去 \(k\) 就好了

# include <bits/stdc++.h>
using namespace std;
typedef long long ll; int n, m, k, mod, g, pr[233333], tot, a[105][105];
int xi[105], yi[105]; struct Edge {
int u, v, w;
} edge[10005]; inline int Pow(ll x, int y) {
register ll ret = 1;
for (; y; y >>= 1, x = x * x % mod)
if (y & 1) ret = ret * x % mod;
return ret;
} inline void Inc(int &x, int y) {
x = x + y >= mod ? x + y - mod : x + y;
} inline void Getrt() {
register int x, i, j;
for (x = mod - 1, i = 2; i * i <= x; ++i)
if (x % i == 0) {
pr[++tot] = i;
while (x % i == 0) x /= i;
}
if (x > 1) pr[++tot] = x;
for (x = mod - 1, i = 2; i <= x; ++i) {
for (g = i, j = 1; g && j <= tot; ++j)
if (Pow(g, x / pr[j]) == 1) g = 0;
if (g) break;
}
} inline int Gauss() {
register int ans = 1, i, j, l, inv;
for (i = 1; i < n; ++i) {
for (j = i; j < n; ++j)
if (a[j][i]) {
if (i != j) swap(a[i], a[j]), ans = mod - ans;
break;
}
for (j = i + 1; j < n; ++j)
if (a[j][i]) {
inv = (ll)a[j][i] * Pow(a[i][i], mod - 2) % mod;
for (l = i; l < n; ++l) Inc(a[j][l], mod - (ll)a[i][l] * inv % mod);
}
ans = (ll)ans * a[i][i] % mod;
}
return ans;
} int main() {
register int i, j, w, u, v, ans;
scanf("%d%d%d%d", &n, &m, &k, &mod), Getrt();
for (i = 1; i <= m; ++i) scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
xi[0] = 1, xi[1] = Pow(g, (mod - 1) / k);
for (i = 0; i < k; ++i) {
if (i > 1) xi[i] = (ll)xi[i - 1] * xi[1] % mod;
memset(a, 0, sizeof(a));
for (j = 1; j <= m; ++j) {
u = edge[j].u, v = edge[j].v, w = Pow(xi[i], edge[j].w);
Inc(a[u][u], w), Inc(a[v][v], w), Inc(a[u][v], mod - w), Inc(a[v][u], mod - w);
}
yi[i] = Gauss();
}
for (i = ans = 0; i < k; ++i) {
for (w = yi[i], j = 0; j < k; ++j)
if (i ^ j) w = (ll)w * (mod - xi[j]) % mod * Pow((xi[i] + mod - xi[j]) % mod, mod - 2) % mod;
Inc(ans, w);
}
printf("%d\n", ans);
return 0;
}

牛客Wannafly挑战赛23F 计数(循环卷积+拉格朗日插值/单位根反演)的更多相关文章

  1. 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)

    牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...

  2. 牛客~~wannafly挑战赛19~A 队列

    链接:https://www.nowcoder.com/acm/contest/131/A来源:牛客网 题目描述 ZZT 创造了一个队列 Q.这个队列包含了 N 个元素,队列中的第 i 个元素用 Qi ...

  3. 牛客Wannafly挑战赛23 B.游戏

    游戏 题目描述 小N和小O在玩游戏.他们面前放了n堆石子,第i堆石子一开始有ci颗石头.他们轮流从某堆石子中取石子,不能不取.最后无法操作的人就输了这个游戏.但他们觉得这样玩太无聊了,更新了一下规则. ...

  4. 牛客Wannafly挑战赛11E 白兔的刁难

    传送门 如果大力推单位根反演就可以获得一个 \(k^2logn\) 的好方法 \[ans_{t}=\frac{1}{k}\sum_{i=0}^{k-1}(w_k^{-t})^i(w_k^i+1)^n\ ...

  5. 【牛客Wannafly挑战赛23】F 计数

    题目链接 题意 给定一张边带权的无向图,求生成树的权值和是 k 的倍数的生成树个数模 p 的值. \(n\leq 100,k\leq 100,p\mod k=1\) Sol 看见整除然后 \(p\mo ...

  6. 牛客 Wannafly 挑战赛26D 禁书目录 排列组合 概率期望

    原文链接https://www.cnblogs.com/zhouzhendong/p/9781060.html 题目传送门 - NowCoder Wannafly 26D 题意 放一放这一题原先的题面 ...

  7. 牛客Wannafly挑战赛26E 蚂蚁开会(树链剖分+线段树)

    传送门 题面描述 一颗n个节点的树,m次操作,有点权(该节点蚂蚁个数)和边权(相邻节点的距离). 三种操作: 操作1:1 i x将节点i的点权修改为x.(1 <= i <= n; 1 &l ...

  8. 牛客 Wannafly挑战赛27 D 绿魔法师

    传送门 \(\color{green}{solution}\) 分析下,在\(1e5+1\)内,一个数的约数个数最多为\(2^{6}\)个,所以我们可以考虑枚举约数 复杂度\(O(N^{2^{6 \t ...

  9. [牛客Wannafly挑战赛27D]绿魔法师

    description newcoder 给你一个空的可重集合\(S\). \(n\)次操作,每次操作给出\(x\),\(k\),\(p\),执行以下操作: \(opt\ 1\):在S中加入x. \( ...

随机推荐

  1. Could not parse UiSelector argument: 'XXX' is not a string 错误解决办法

    ebDriverWait(driver,20).until(EC.visibility_of_element_located((MobileBy.ANDROID_UIAUTOMATOR,new UiS ...

  2. vue-cli3 chainWebpack配置,去除打包后文件的预加载prefetch/preload(已解决)

    //细节配置修改 chainWebpack: config => { console.log(config,'chainWebpack') // 移除 prefetch 插件 config.pl ...

  3. windows下python管理右键菜单

    实现很简单,不记得什么时候写的了,贴出来希望能有所价值 """ Windows中创建右键菜单 """ import os import sy ...

  4. Scrapyd-Client的安装

    1. pip安装 这里推荐使用pip安装,相关命令如下: pip3 install scrapyd-client 2.验证安装 安装成功后会有一个可用命令,叫作scrapyd-deploy,即部署命令 ...

  5. Mac 10.12安装飞鸽传书IPMessager

    说明:这个版本的飞鸽传书不能和Linux的互通,但是可以和Windows的互通,我猜测是协议问题:如果想要互通只能是Mac和Linux同时安装iptux. 下载: (链接: https://pan.b ...

  6. HTTP传输数据压缩

    一.基础 1.HTTP压缩是指: Web服务器和浏览器之间压缩传输的”文本内容“的方法. HTTP采用通用的压缩算法,比如gzip来压缩HTML,Javascript, CSS文件. 能大大减少网络传 ...

  7. 003javascript语句

    javascript语句和java差不多,注意==和===区别 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" " ...

  8. Django的国际化

    Django的国际化 Django基于python的gettext来实现国际化.其过程为安装gettext工具,然后再代码中调用指定方法,然后用gettext提供的程序来把代码中需要翻译的部分找出来写 ...

  9. Velocity初始化过程解析

    velocity就是由template,engine,context组成. 1.首先创建一个template(如果是用在web上就是一个html文件),将需要参数化或实例化的地方用跟context有关 ...

  10. js empty() vs remove()

    转自:jQuery empty() vs remove() empty() will remove all the contents of the selection. remove() will r ...