@description@

输入 n(n ≤ 22) 个点,m(m ≤ 8000) 个边。每个边连接着点 (si, ei),有两个长度 fi, ri。

问对于每个点 k,有多少条路径(不一定是简单路径)由 t (t ≤ 10^9) 条边组成,从 k 开始,并且以 k 结束;并且路径上所有边 f 的和 mod n 为 x;并且路径上所有边 r 的和 mod (n − 1) 为 y。

对于每一个 (x, y) 都要计算。

方案数 mod 1163962801 输出。

input

输入的第一行包含三个整数 n、m 和 t。n, m, t 的含义如上,注意 n 是点数,也是模数。如果重复经过同一条边,需要计算两次。

之后的 m 行里,每一行表示一条边。其中第 i 行包含四个整数,分别代表 si, ei, fi, ri。含义如上。

可能有重边自环。

output

输出被分为 n 个部分。其中第 k 个部分 (1 ≤ k ≤ n) 包含 n 行,而每一行包含 n − 1 个整数。

第 k 个输出部分的第 i 行的第 j 个数应当表示从点 k 出发,走过 t 条边之后回到点 k,路径上所有边 f 的和 mod n 为 i;并且路径上所有边 r 的和 mod (n − 1) 为 j。

输出的所有数字都应当对 1163962801 取模。

sample input

3 6 6

1 2 0 0

2 1 1 1

1 3 1 2

3 1 2 1

2 3 5 5

3 2 10 10

sample output

1 5

0 10

1 5

1 5

0 10

1 5

1 8

0 10

1 2

@solution@

首先观察到 n 的范围很小,t 的范围很大,并且可以经过重复的边。不难想到使用矩阵加速。

一个很 naive 的想法是,我们对于矩阵的每一个位置 (i, j) 记录 n*(n-1) 个二元组 (x, y),表示从 i 到 j 路径上所有边 f 的和 mod n 为 x,r 的和 mod (n − 1) 为 y 的方案数。

这样做矩阵乘法 \(C = A*B\) 的时候,\(C(i, j) = \sum A(i, k)*B(k, j)\) 实际上就是 \(C(i, j, (x+p) \mod n, (y+q) \mod (n-1)) = \sum(A(i, k, x, y) * B(k, j, p, q))\)。

要做 \(O(n^3)\) 次乘法,每次乘法 \(O(n^4)\)。时间复杂度 \(O(n^7*log k)\)。虽然 n 很小但还是太慢了。

观察我们乘法的转移形式,不难发现它是一个循环卷积的形式,可以使用 fft 优化。

优化过后每次乘法只需要 \(O(n^2*log n)\) 的时间,时间复杂度降为 \(O(n^5*log n*log k)\)。

但是注意到模数不是 998244353 而是 1163962801,所以这里的 fft 必须要使用一些常数较大的技巧来避免溢出。

所以实际运行时效果远不如 \(O(n^5*log n*log k)\) 那么优秀。

考虑我们平常使用多项式作快速幂,是将其转为点值形式,使用点值做快速幂。这个地方是否也可以运用这一方法呢。

对于长度为 n 的循环卷积,无法将其长度拓展为 2 的幂,所以无法使用一般的 fft。

但是,代入 n 次单位根很多性质依然可以满足。或者说,除了不能使用分治进行 fft,其他性质都可以满足。

注意到这个地方的 n 很小,我们可以直接暴力 \(O(n^2)\) 求值,暴力 \(O(n^2)\) 还原。

观察模数 mod = 1163962801。想一想为什么可以使用 p = 998244353 进行数论变换,因为 p-1 恰好是 2^23 的倍数,所以它有 2^x(x ≤ 23) 次单位根。

对 mod - 1 进行质因数分解,它等于 \(2^4*3^2*5^2*7*11*13*17*19\)。我们发现它是 1~22 所有数字的公倍数,因此它有 1~22 次单位根。

最后一个问题,这个地方是一个二维的卷积形式。

因此,我们求值时是代入一个二元组 \((w_n^i, w_{n-1}^j)\),一共有 n*(n-1) 对二元组要求值。

最后逆变换还原时,插值 \((w_n^{-i}, w_{n-1}^{-j})\) 即可。直观理解起来不难。

时间复杂度为 \(O(n^5*log k)\)。

@accepted code@

#include<cstdio>
const int G = 46;
const int MAXN = 22 + 5;
const int MAXM = 10000 + 5;
const int MOD = 1163962801;
inline int add(int x, int y) {return (1LL*x + 1LL*y)%MOD;}
inline int mul(int x, int y) {return 1LL*x*y%MOD;}
int pow_mod(int b, int p) {
int ret = 1;
while( p ) {
if( p & 1 ) ret = mul(ret, b);
b = mul(b, b);
p >>= 1;
}
return ret;
}
struct matrix{
int m[MAXN][MAXN], r, c;
friend matrix operator * (const matrix &A, const matrix &B) {
matrix C; C.r = A.r, C.c = B.c;
for(int i=0;i<C.r;i++)
for(int j=0;j<C.c;j++) {
C.m[i][j] = 0;
for(int k=0;k<A.c;k++) {
C.m[i][j] = add(C.m[i][j], mul(A.m[i][k], B.m[k][j]));
}
}
return C;
}
};
matrix mpow(matrix A, int p) {
matrix ret; ret.r = ret.c = A.r;
for(int i=0;i<A.r;i++)
for(int j=0;j<A.c;j++)
ret.m[i][j] = (i == j);
while( p ) {
if( p & 1 ) ret = ret * A;
A = A * A;
p >>= 1;
}
return ret;
}
void func(int a[], int n) {
a[0] = 1, a[1] = pow_mod(G, (MOD - 1)/n);
for(int i=2;i<n;i++) a[i] = mul(a[i - 1], a[1]);
}
int wx[MAXN], wy[MAXN];
int u[MAXM], v[MAXM], x[MAXM], y[MAXM];
int t, n, m;
matrix get_matrix(int i, int j) {
matrix A; A.r = A.c = n;
for(int k=0;k<A.r;k++)
for(int l=0;l<A.c;l++)
A.m[k][l] = 0;
for(int k=1;k<=m;k++)
A.m[u[k]][v[k]] = add(A.m[u[k]][v[k]], mul(pow_mod(wx[i], x[k]), pow_mod(wy[j], y[k])));
return A;
}
int f[MAXN][MAXN][MAXN];
int ans[MAXN][MAXN];
void func2(int i) {
for(int j=0;j<n;j++)
for(int k=0;k<n-1;k++)
ans[j][k] = 0;
for(int j=0;j<n;j++)
for(int k=0;k<n-1;k++)
for(int p=0;p<n;p++)
for(int q=0;q<n-1;q++) {
ans[j][k] = add(ans[j][k], mul(f[i][p][q], mul(pow_mod(wx[j], n-p), pow_mod(wy[k], (n-1)-q))));
}
int inv = pow_mod(n*(n - 1), MOD - 2);
for(int j=0;j<n;j++)
for(int k=0;k<n-1;k++)
printf("%d%c", mul(ans[j][k], inv), (k + 1 == n - 1) ? '\n' : ' ');
}
int main() {
scanf("%d%d%d", &n, &m, &t);
for(int i=1;i<=m;i++) {
scanf("%d%d%d%d", &u[i], &v[i], &x[i], &y[i]);
u[i]--, v[i]--, x[i] %= n, y[i] %= (n-1);
}
func(wx, n), func(wy, n - 1);
for(int i=0;i<n;i++)
for(int j=0;j<n-1;j++) {
matrix M = mpow(get_matrix(i, j), t);
for(int k=0;k<n;k++)
f[k][i][j] = M.m[k][k];
}
for(int i=0;i<n;i++)
func2(i);
}

@details@

这道题的模数,加法刚好溢出 int。

我就说为什么它会出现负数……

2017 冬令营的老题了……

@codechef - BIKE@ Chef and Bike的更多相关文章

  1. 【Codechef】Chef and Bike(二维多项式插值)

    something wrong with my new blog! I can't type matrixs so I come back. qwq 题目:https://www.codechef.c ...

  2. [Codechef CHSTR] Chef and String - 后缀数组

    [Codechef CHSTR] Chef and String Description 每次询问 \(S\) 的子串中,选出 \(k\) 个相同子串的方案有多少种. Solution 本题要求不是很 ...

  3. 【CodeChef】Chef and Graph Queries

    Portal --> CC Chef and Graph Queries Solution 快乐数据结构题(然而好像有十分优秀的莫队+可撤销并查集搞法qwq) 首先考虑一种方式来方便一点地..计 ...

  4. [CodeChef - GERALD07 ] Chef and Graph Queries

    Read problems statements in Mandarin Chineseand Russian. Problem Statement Chef has a undirected gra ...

  5. CodeChef CHEFSOC2 Chef and Big Soccer 水dp

    Chef and Big Soccer   Problem code: CHEFSOC2 Tweet     ALL SUBMISSIONS All submissions for this prob ...

  6. Codechef FNCS Chef and Churu

    Disciption Chef has recently learnt Function and Addition. He is too exited to teach this to his fri ...

  7. CodeChef - FNCS Chef and Churu(分块)

    https://vjudge.net/problem/CodeChef-FNCS 题意: 思路: 用分块的方法,对每个函数进行分块,计算出该分块里每个数的个数,这样的话也就能很方便的计算出这个分块里所 ...

  8. 【xsy2111】 【CODECHEF】Chef and Churus 分块+树状数组

    题目大意:给你一个长度为$n$的数列$a_i$,定义$f_i=\sum_{j=l_i}^{r_i} num_j$. 有$m$个操作: 操作1:询问一个区间$l,r$请你求出$\sum_{i=l}^{r ...

  9. codechef T2 Chef and Sign Sequences

    CHEFSIGN: 大厨与符号序列题目描述 大厨昨天捡到了一个奇怪的字符串 s,这是一个仅包含‘<’.‘=’和‘>’三种比较符号的字符串. 记字符串长度为 N,大厨想要在字符串的开头.结尾 ...

随机推荐

  1. LintCode_50 数组剔除元素后的乘积

    题目 给定一个整数数组A. 定义B[i] = A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1], 计算B的时候请不要使用除法. 样例 给出A=[1, 2, 3], ...

  2. python 数据标准化

  3. 【模板】矩阵快速幂 洛谷P2233 [HNOI2002]公交车路线

    P2233 [HNOI2002]公交车路线 题目背景 在长沙城新建的环城公路上一共有8个公交站,分别为A.B.C.D.E.F.G.H.公共汽车只能够在相邻的两个公交站之间运行,因此你从某一个公交站到另 ...

  4. Mysql的CMD操作

    一.MySQL登录和退出——在CMD模式操作 l  语法格式:mysql.exe –h主机名 –u用户名 –p密码 l  参数说明:   mysql.exe是mysql服务器的主应用程序.   -h代 ...

  5. xmlns详解(转载)

    我们经常会在网页中碰到形如<html xmlns=”http://www.w3.org/2001/xhtml”>这样的代码, 或在是android 编码中的main.xml中看到形如< ...

  6. 强力Django+杀手级xadmin开发在线教育网站

    强力Django+杀手级xadmin开发在线教育网站采用 Python3.7全新开发 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的 ...

  7. ie8或9下ajax跨域问题

    ie8或9下ajax跨域支持,添加如下代码 <!--[if (IE 8)|(IE 9)]><script src="https://cdn.bootcss.com/jque ...

  8. Percona XtraBackup 完全及增量备份与恢复的方法

    安装及备份.恢复实现 安装:其最新版的软件可从 http://www.percona.com/software/percona-xtrabackup/ 获得.本文基于CentOS6.x的系统,因此,直 ...

  9. Mysql+php报错原因

    SQL syntax --语法错误,看near,错误会在near后引号中的内容 的附近 Table/Database....... dosen't existes ---表/库(库名/表名) 不存在 ...

  10. SpringMvc表单标签库

    HTML密码框 <td><form:label path="password">密码:</form:label></td><t ...