洛谷很早以前就写过了,今天交到bzoj发现TLE了。

检查了一下发现自己复杂度是错的。

题目传送门:洛谷P3704

题意简述:

求 \(\prod_{i=1}^{N}\prod_{j=1}^{M}F_{\gcd(i,j)}\bmod mod\) ,其中 \(F_{i}\) 是斐波那契数列的第 \(i\) 项, \(mod=10^9+7\) 。

\(T\) 组数据。

题解:

喜闻乐见的推式子时间。

不失一般性,假设 \(N\le M\) 。

\[\begin{aligned}&\prod_{i=1}^{N}\prod_{j=1}^{M}F_{\gcd(i,j)} \\=&\prod_{k=1}^{N}{F_{k}}^{\left(\sum_{i=1}^{N}\;\sum_{j=1}^{M}\;\left[\gcd(i,j)=k\right]\right)}\end{aligned}\]

右上角的指数部分是老套路了。

\[\begin{align*}&= \sum_{i=1}^{N}\sum_{j=1}^{M}\left[\gcd(i,j)=k\right]\\&= \sum_{i=1}^{\left\lfloor\frac{N}{k}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{M}{k}\right\rfloor}\left[\gcd(i,j)=1\right]\\&= \sum_{d=1}^{\left\lfloor\frac{N}{k}\right\rfloor}\mu(d)\left\lfloor\frac{N}{kd}\right\rfloor\left\lfloor\frac{M}{kd}\right\rfloor\end{align*}\]

所以

\[\begin{align*} &= \prod_{k=1}^{N}{F_{k}}^{\left(\sum_{d=1}^{\left\lfloor\frac{N}{k}\right\rfloor}\mu(d)\left\lfloor\frac{N}{kd}\right\rfloor\left\lfloor\frac{M}{kd}\right\rfloor\right)}\\ &= \prod_{T=1}^{N}\left(\prod_{k|T}{F_{k}}^{\mu(\frac{T}{k})}\right)^{\left\lfloor\frac{N}{T}\right\rfloor\left\lfloor\frac{M}{T}\right\rfloor} \end{align*}\]

令 \(f(n)=\prod_{d|n}{F_{d}}^{\mu(\frac{n}{d})}\) 。

\[=\prod_{T=1}^{N}{f(T)}^{\left\lfloor\frac{N}{T}\right\rfloor\left\lfloor\frac{M}{T}\right\rfloor}\]

外层数论分块求出。内层的 \(f(T)\) 直接暴力预处理,每个数直接乘到它的倍数中,复杂度 \(\Theta(n\log n)\)。

注意实现的时候的时间复杂度,我因为实现多了快速幂的一个 \(\log\) 被卡了。

正确的时间复杂度应该是 \(\Theta(N(\log N+\log mod)+T\sqrt{N}\log mod)\) 。

 #include<cstdio>
#include<algorithm>
using namespace std; #define mod 1000000007
#define LL long long int Pow(int b, LL e) {
if (e < ) e += mod - ;
int a = ;
for (; e; b = (LL)b * b % mod, e >>= )
if (e & ) a = (LL)a * b % mod;
return a;
} bool ip[];
int p[], pc;
int mu[];
int f[], fr[]; void init() { ip[] = ;
mu[] = ; for (int i = ; i <= ; ++i) {
if (!ip[i]) {
p[++pc] = i;
mu[i] = -;
}
for (int j = ; j <= pc && (LL)p[j] * i <= ; ++j) {
register int k = p[j] * i;
ip[k] = ;
if (i % p[j]) mu[k] = -mu[i];
else break;
}
} for (int i = ; i <= ; ++i)
f[i] = , fr[i] = ; int A = , B = ;
for (int i = ; i <= ; ++i) {
B = (A + B) % mod;
A = (B - A + mod) % mod;
int G[] = {Pow(B, -), , B};
for (int j = i, k = ; j <= ; j += i, ++k) {
f[j] = (LL)f[j] * G[mu[k] + ] % mod,
fr[j] = (LL)fr[j] * G[ - mu[k]] % mod;
}
} f[] = fr[] = ;
for (int i = ; i <= ; ++i)
f[i] = (LL)f[i - ] * f[i] % mod,
fr[i] = (LL)fr[i - ] * fr[i] % mod;
} int main() {
init();
int T;
scanf("%d", &T);
while (T--) {
int N, M;
scanf("%d%d", &N, &M);
if (N > M) swap(N, M);
int A = ;
for (int i = , j; i <= N; i = j + ) {
j = min(N / (N / i), M / (M / i));
A = (LL)A * Pow((LL)f[j] * fr[i - ] % mod, (LL)(N / i) * (M / i)) % mod;
}
printf("%d\n", A);
}
return ;
}

bzoj 4816: 洛谷 P3704: [SDOI2017]数字表格的更多相关文章

  1. 洛谷P3704 [SDOI2017]数字表格

    题目描述 Doris刚刚学习了fibonacci数列.用f[i]f[i] 表示数列的第ii 项,那么 f[0]=0f[0]=0 ,f[1]=1f[1]=1 , f[n]=f[n-1]+f[n-2],n ...

  2. 洛谷 P3704 [SDOI2017]数字表格(莫比乌斯函数)

    题面传送门 题意: 求 \[\prod\limits_{i=1}^n\prod\limits_{j=1}^mfib_{\gcd(i,j)} \] \(T\) 组测试数据,\(1 \leq T \leq ...

  3. 洛谷P3704 [SDOI2017]数字表格(莫比乌斯反演)

    传送门 yyb大佬太强啦…… 感觉还是有一点地方没有搞懂orz //minamoto #include<cstdio> #include<iostream> #include& ...

  4. 洛谷 P3704 SDOI2017 数字表格

    题意: 给定两个整数 \(n, m\),求: \[\prod_{i = 1} ^ n \prod_{j = 1} ^ m \operatorname{Fib}_{\gcd\left(n, m\righ ...

  5. 洛谷3704 [SDOI2017] 数字表格 【莫比乌斯反演】

    题目分析: 比较有意思,但是套路的数学题. 题目要求$ \prod_{i=1}^{n} \prod_{j=1}^{m}Fib(gcd(i,j)) $. 注意到$ gcd(i,j) $有大量重复,采用莫 ...

  6. 洛咕 P3704 [SDOI2017]数字表格

    大力推式子 现根据套路枚举\(\gcd(i,j)\) \(ans=\Pi_{x=1}^nfib[x]^{\sum_{i=1}^{n/x}\sum_{j=1}^{n/x}[\gcd(i,j)=1]}\) ...

  7. P3704 [SDOI2017]数字表格

    P3704 [SDOI2017]数字表格 链接 分析: $\ \ \ \prod\limits_{i = 1}^{n} \prod\limits_{j = 1}^{m} f[gcd(i, j)]$ $ ...

  8. P3704 [SDOI2017]数字表格 (莫比乌斯反演)

    [题目链接] https://www.luogu.org/problemnew/show/P3704 [题解] https://www.luogu.org/blog/cjyyb/solution-p3 ...

  9. luogu P3704 [SDOI2017]数字表格

    传送门 我是真的弱,推式子只能推一半 下面假设\(n<m\) 考虑题目要求的东西,可以考虑每个gcd的贡献,即\[\prod_{d=1}^{n}f[d]^{\sum_{i=1}^{\lfloor ...

随机推荐

  1. java 构造器二

  2. java 创建过程

  3. BZOJ5127 数据校验

    第一眼看错题以为只是要求区间值域连续,那莫队一发维护形成的值域段数量就行了. 原题这个条件相当于区间内相邻数差的绝对值不超过1.所以只要对这个做个前缀和就……完了? #include<iostr ...

  4. c++11 左值引用、右值引用

    c++11 左值引用.右值引用 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #i ...

  5. 【UOJ#80】二分图最大权匹配(KM)

    题面 UOJ 题解 模板qaq #include<iostream> #include<cstdio> #include<cstdlib> #include< ...

  6. IO编程(1)-文件读写

    文件读写 读写文件是最常见的IO操作.Python内置了读写文件的函数,用法和C是兼容的. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接 ...

  7. servlet与tomcat的关系

    1.4   Tomcat简介 学习Servlet技术,首先需要有一个Servlet运行环境,也就是需要有一个Servlet容器,本书采用的是Tomcat. Tomcat是一个免费的开放源代码的Serv ...

  8. ssh 执行命令并实时显示结果

    ssh 执行命令并实时显示结果 import paramiko def main(): sshClient = paramiko.SSHClient() sshClient.set_missing_h ...

  9. ICMP类型和代号对照表

    ICMP类型 TYPE CODE Description Query Error 0 0 Echo Reply——回显应答(Ping应答) x   3 0 Network Unreachable——网 ...

  10. VMware 安装Ubuntu16.04时显示不全的解决方法

    实际安装时发现进行到分区这个步骤时,看不到下面的按钮, 百度后得知有此遭遇的不在少数,是因为系统默认分辨率与电脑分辨率的差异导致的. 解决方法也很简单粗暴: 左手按住alt键右手鼠标往上拖动安装界面, ...