题目

Doris刚刚学习了fibonacci数列。用f[i]表示数列的第i项,那么

f[0]=0

f[1]=1

f[n]=f[n-1]+f[n-2],n>=2

Doris用老师的超级计算机生成了一个n×m的表格,第i行第j列的格子中的数是f[gcd(i,j)],其中gcd(i,j)表示i,

j的最大公约数。Doris的表格中共有n×m个数,她想知道这些数的乘积是多少。答案对10^9+7取模。

输入格式

有多组测试数据。

第一个一个数T,表示数据组数。

接下来T行,每行两个数n,m

T<=1000,1<=n,m<=10^6

输出格式

输出T行,第i行的数是第i组数据的结果

输入样例

3

2 3

4 5

6 7

输出样例

1

6

960

题解

一道满是套路的莫比乌斯反演题

我们要求:

\[\prod\limits_{i=1}^{N}\prod\limits_{j=1}^{M} f[gcd(i,j)]
\]

根据莫比乌斯反演的套路,我们将gcd改为枚举d

\[\prod\limits_{d=1}^{N} f[d]^{\sum\limits_{i=1}^{N}\sum\limits_{j=1}^{M} 1 [gcd(i,j) == d]}
\]

然后把指数中的\(d\)提掉

\[\prod\limits_{d=1}^{N} f[d]^{\sum\limits_{i=1}^{\lfloor \frac{N}{d} \rfloor}\sum\limits_{j=1}^{\lfloor \frac{M}{d} \rfloor} 1 [gcd(i,j) == 1]}
\]

然后指数部分就是经典的莫比乌斯反演

\[\prod\limits_{d=1}^{N} f[d]^{\sum\limits_{i=1}^{\lfloor \frac{N}{d} \rfloor} \mu(i) * \lfloor \frac{N}{i * d} \rfloor * \lfloor \frac{M}{i * d} \rfloor}
\]

如果只有一组询问,这样接近\(O(n)\)可以过,但是多组询问,我们考虑继续优化

我们有一个枚举\(i * d\)的套路

我们记\(T = i * d\)

\[\prod\limits_{T=1}^{N} \prod\limits_{d|T} f[d]^{\mu(\frac{T}{d}) * \lfloor \frac{N}{T} \rfloor * \lfloor \frac{M}{T} \rfloor}
\]

划分一下:

\[\prod\limits_{T=1}^{N} ( \prod\limits_{d|T} f[d]^{\mu(\frac{T}{d})} ) ^ {\lfloor \frac{N}{T} \rfloor * \lfloor \frac{M}{T} \rfloor}
\]

容易发现,内层的东西就是关于\(T\)的因子的积,根据经验,这玩意可以通过枚举\(O(nlogn)\)预处理

外层是只与\(T\)有关的整除,可以\(O(\sqrt{N})\)分块

那我们就用\(O(nlogn + T\sqrt{N})\)的复杂度做完了

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
#define res register
using namespace std;
const int maxn = 1000005,maxm = 100005,INF = 1000000000,P = 1000000007,md = 1000000006;
int fv[maxn],f[maxn],g[maxn],gv[maxn];
int mu[maxn],p[maxn],fac[maxn],pi;
int isn[maxn];
int qpow(int a,LL b){
b = (b % md + md) % md;
int ans = 1;
for (; b; b >>= 1,a = (LL)a * a % P)
if (b & 1) ans = (LL)ans * a % P;
return ans;
}
void init(){
mu[1] = 1;
for (res int i = 2; i < maxn; i++){
if (!isn[i]) p[++pi] = i,mu[i] = -1;
for (res int j = 1; j <= pi && i * p[j] < maxn; j++){
isn[i * p[j]] = true;
if (i % p[j] == 0){
mu[i * p[j]] = 0;
break;
}
mu[i * p[j]] = -mu[i];
}
}
f[0] = 0; f[1] = 1;
fv[0] = 1; fv[1] = 1;
for (res int i = 2; i < maxn; i++){
f[i] = (f[i - 1] + f[i - 2]) % P;
fv[i] = qpow(f[i],P - 2);
}
for (res int i = 1; i < maxn; i++) g[i] = 1;
for (res int i = 1; i < maxn; i++){
for (int j = i; j < maxn; j += i){
if (mu[j / i] == 1) g[j] = (LL)g[j] * f[i] % P;
if (mu[j / i] == -1) g[j] = (LL)g[j] * fv[i] % P;
}
}
g[0] = gv[0] = 1;
gv[1] = qpow(g[1],P - 2);
for (res int i = 2; i < maxn; i++){
g[i] = (LL)g[i] * g[i - 1] % P;
gv[i] = qpow(g[i],P - 2);
}
}
int main(){
init();
int n,m,T;
LL ans;
cin >> T;
while (T--){
cin >> n >> m;
ans = 1;
if (n > m) swap(n,m);
for (res int i = 1,nxt; i <= n; i = nxt + 1){
nxt = min(n / (n / i),m / (m / i));
ans = (LL)ans * qpow((LL)g[nxt] * gv[i - 1] % P,(LL)(n / i) * (m / i)) % P;
}
cout << ans << endl;
}
return 0;
}

BZOJ4816 [Sdoi2017]数字表格 【莫比乌斯反演】的更多相关文章

  1. BZOJ4816 SDOI2017 数字表格 莫比乌斯反演

    传送门 做莫比乌斯反演题显著提高了我的\(\LaTeX\)水平 推式子(默认\(N \leq M\),分数下取整,会省略大部分过程) \(\begin{align*} \prod\limits_{i= ...

  2. [Sdoi2017]数字表格 [莫比乌斯反演]

    [Sdoi2017]数字表格 题意:求 \[ \prod_{i=1}^n \prod_{j=1}^m f[(i,j)] \] 考场60分 其实多推一步就推倒了... 因为是乘,我们可以放到幂上 \[ ...

  3. 【bzoj4816】[Sdoi2017]数字表格 莫比乌斯反演

    题目描述 Doris刚刚学习了fibonacci数列.用f[i]表示数列的第i项,那么 f[0]=0 f[1]=1 f[n]=f[n-1]+f[n-2],n>=2 Doris用老师的超级计算机生 ...

  4. [bzoj4816][Sdoi2017]数字表格 (反演+逆元)

    (真不想做莫比乌斯了) 首先根据题意写出式子 ∏(i=1~n)∏(j=1~m)f[gcd(i,j)] 很明显的f可以预处理出来,解决 根据套路分析,我们可以先枚举gcd(i,j)==d ∏(d=1~n ...

  5. BZOJ.4816.[SDOI2017]数字表格(莫比乌斯反演)

    题目链接 总感觉博客园的\(Markdown\)很..\(gouzhi\),可以看这的. 这个好像简单些啊,只要不犯sb错误 [Update] 真的算反演中比较裸的题了... \(Descriptio ...

  6. BZOJ 4816 [Sdoi2017]数字表格 ——莫比乌斯反演

    大力反演出奇迹. 然后xjb维护. 毕竟T1 #include <map> #include <ctime> #include <cmath> #include & ...

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

    link 设\(f_0=0,f_1=1,f_n=f_{n-1}+f_{n-2}(n\ge 2)\) 求\(\prod_{i=1}^n\prod_{j=1}^mf_{\gcd(i,j)}\),多组询问, ...

  8. [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块)

    [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块) 题面 求 \[\sum_{i=1}^{n} \sum_{j=1}^{m} \mathrm{lcm}(i,j)\] 分析 \[\su ...

  9. [SDOI2017]数字表格 --- 套路反演

    [SDOI2017]数字表格 由于使用markdown的关系 我无法很好的掌控格式,见谅 对于这么简单的一道题竟然能在洛谷混到黑,我感到无语 \[\begin{align*} \prod\limits ...

  10. 【BZOJ4816】【SDOI2017】数字表格 [莫比乌斯反演]

    数字表格 Time Limit: 50 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Doris刚刚学习了fibonac ...

随机推荐

  1. ucos-ii核心算法分析(转)

    μC/OS-Ⅱ是一种免费公开源代码.结构小巧.具有可剥夺实时内核的实时操作系统.其 内核提供任务调度与管理.时间管理.任务间同步与通信.内存管理和中断服务等功能.适合小型控制系统,具有执行效率高.占用 ...

  2. 2018.5.13 oracle遇到的问题

    安装Oracle 11g 出现交换空间不够 在计算机那里右键打开属性进入高级系统设置然后找到第一个设置找到高级然后更改一下自定义范围(云服务器是16-10000) 然后确定 完成了. 快安装结束之后显 ...

  3. ubuntu下安装eclipse<转>

    转载自http://my.oschina.net/u/1407116/blog/227084      http://my.oschina.net/u/1407116/blog/227087 一 JD ...

  4. Git初始化仓库

    Git global setup: git config --global user.name "再见理想" git config --global user.email &quo ...

  5. DROP OPERATOR CLASS - 删除一个操作符类

    SYNOPSIS DROP OPERATOR CLASS name USING index_method [ CASCADE | RESTRICT ] DESCRIPTION 描述 DROP OPER ...

  6. 多线程编程之pthread线程深入理解

    不同的平台和操作系统上 进程和线程的实现机制不完全一致  但是一般来说线程栈都是独立的 只要得到地址就可以相互访问       Pthread是 POSIX threads 的简称,是POSIX的线程 ...

  7. iOS应用架构谈-part1概述

    当我们讨论客户端应用架构的时候,我们在讨论什么? 其实市面上大部分应用不外乎就是颠过来倒过去地做以下这些事情: --------------- --------------- ------------ ...

  8. ES6学习总结 (二)

    一:ES6为函数做了哪些扩展 参数的默认值 传统写法: function person(n,a){ var name =n || "zhangsan"; var age = a | ...

  9. 状态压缩dp 状压dp 详解

    说到状压dp,一般和二进制少不了关系(还常和博弈论结合起来考,这个坑我挖了还没填qwq),二进制是个好东西啊,所以二进制的各种运算是前置知识,不了解的话走下面链接进百度百科 https://baike ...

  10. NowCoder 9.9 模拟赛

    T1.中位数 二分答案x,原序列大于x的置为1,小于x的置为-1,判断是否存在长度大于m的区间和大于0(也就是大于x的数多于小于x的数),若有,则ans>=x,否则ans<x #inclu ...