4816: [Sdoi2017]数字表格

Time Limit: 50 Sec  Memory Limit: 128 MB

Description

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取模。

Input

有多组测试数据。

第一个一个数T,表示数据组数。
接下来T行,每行两个数n,m
T<=1000,1<=n,m<=10^6

Output

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

Sample Input

3
2 3
4 5
6 7

Sample Output

1
6
960

题解

这道题很好地延续了SDOI的优良传统,考了一道莫比乌斯反演以供娱乐。

由于我们一眼发现了这是一道莫比乌斯反演水题,正如做所有的莫比乌斯反演一样,我们把要求的式子先写出来并推导

\begin{eqnarray*}
ans & = & \prod_{i}^{n}\prod _{j}^{m}f( \gcd(i,j) ) \\
& = & \prod_{k}^{n}f(k) ^ {\sum_{i}^{\frac{n}{k}}\sum_{j}^{\frac{m}{k}}[\gcd(i,j)=1]} \\
& = & \prod_{k}^{n}f(k) ^ {\sum_{i}^{\frac{n}{k}}\sum_{j}^{\frac{m}{k}}\sum_{x\mid{i}\&x\mid{j}}~~\mu(x)} \\
& = & \prod_{k}^{n}\prod_{x}^{\frac{n}{k}}(f(k) ^ {\mu(x)})^{\frac{n}{kx}\frac{m}{kx}}
\end{eqnarray*}

为了能够把\(f(k) ^ {\mu(x)}\)提出来,显然,我们可以设\(T=kx\),\(g(T)=\prod_{k\mid{T}}f(k) ^ {\mu(\frac{T}{k})}\)

化简得到\(ans = \prod_{T}^{n}g(T)^{\frac{n}{T}\frac{m}{T}}\)

求出$f$以及$f$的逆元,线性筛求$\mu$,Dirichlet卷积求出$g$,然后计算$g$的前缀积$g'$以及$g'$的逆元

查询使用大众喜闻乐见的分块,至此,我们切掉了这道水题。

代码

#include<bits/stdc++.h>
using namespace std;
template <class _T> inline void read(_T &_x) {
int _t; bool flag = false;
while ((_t = getchar()) != '-' && (_t < '' || _t > '')) ;
if (_t == '-') _t = getchar(), flag = true; _x = _t - '';
while ((_t = getchar()) >= '' && _t <= '') _x = _x * + _t - '';
if (flag) _x = -_x;
}
typedef long long LL;
const int maxn = ;
const int mod = ;
int f[maxn], f_re[maxn], mu[maxn], g[maxn], g_re[maxn];
bool vis[maxn]; int prime[maxn / ], pcnt;
#define trans(x) ((int)((LL)x % mod))
#define reg register
inline void update(int &a, reg int b) {
a = trans(a * b);
if (a < ) a += mod;
}
inline int qpower(int a, reg LL b) {
int ret = ;
while (b) {
if (b & ) update(ret, a);
update(a, a), b >>= ;
}
return ret;
}
inline int calc(reg int a, reg int b) {
if (b == ) return ;
return b < ? f_re[a] : f[a];
}
void init() {
f[] = , f[] = f_re[] = g[] = mu[] = ;
reg int i, j;
for (i = ; i < maxn; ++i) {
f[i] = f[i - ] + f[i - ];
if (f[i] >= mod) f[i] -= mod;
f_re[i] = qpower(f[i], mod - );
}
for (i = ; i < maxn; ++i) {
g[i] = ;
if (!vis[i]) {
prime[++pcnt] = i;
mu[i] = -;
}
for (j = ; j <= pcnt && prime[j] * i < maxn; ++j) {
vis[i * prime[j]] = true;
if (i % prime[j] == ) {
mu[i * prime[j]] = ;
break;
}
mu[i * prime[j]] = -mu[i];
}
}
for (i = ; i * i < maxn; ++i) {
update(g[i * i], calc(i, mu[i]));
for (j = i + ; i * j < maxn; ++j)
update(g[i * j], trans(calc(i, mu[j]) * calc(j, mu[i])));
}
g[] = g_re[] = ;
for (i = ; i < maxn; ++i) {
update(g[i], g[i - ]);
g_re[i] = qpower(g[i], mod - );
}
}
inline int query(reg int a, reg int b) {
if (a > b) {int t = a; a = b, b = t; }
int ret = ;
for (reg int i = , j, x, y; i <= a; i = j + ) {
x = a / i, y = b / i;
j = min(a / x, b / y);
update(ret, qpower(trans(g[j] * g_re[i - ]), (LL)x * y));
}
return ret;
}
int main() {
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
init();
int T, a, b; read(T);
while (T--) {
read(a), read(b);
printf("%d\n", query(a, b));
}
return ;
}

BZOJ4816 数字表格的更多相关文章

  1. 【BZOJ4816】数字表格(莫比乌斯反演)

    [BZOJ4816]数字表格(莫比乌斯反演) 题面 BZOJ 求 \[\prod_{i=1}^n\prod_{j=1}^mf[gcd(i,j)]\] 题解 忽然不知道这个要怎么表示... 就写成这样吧 ...

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

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

  3. BZOJ 2154: Crash的数字表格 [莫比乌斯反演]

    2154: Crash的数字表格 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 2924  Solved: 1091[Submit][Status][ ...

  4. 【BZOJ】【2154】Crash的数字表格

    莫比乌斯反演 PoPoQQQ讲义第4题 题解:http://www.cnblogs.com/jianglangcaijin/archive/2013/11/27/3446169.html 感觉两次sq ...

  5. 【莫比乌斯反演】关于Mobius反演与lcm的一些关系与问题简化(BZOJ 2154 crash的数字表格&&BZOJ 2693 jzptab)

    BZOJ 2154 crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b ...

  6. 【BZOJ 2154】Crash的数字表格 (莫比乌斯+分块)

    2154: Crash的数字表格 Description 今天的数学课上,Crash小朋友学习了最小公倍数(Least Common Multiple).对于两个正整数a和b,LCM(a, b)表示能 ...

  7. BZOJ 4816 数字表格

    首先是惯例的吐槽.SDOI题目名称是一个循环,题目内容也是一个循环,基本上过几年就把之前的题目换成另一个名字出出来,喜大普奔亦可赛艇.学长说考SDOI可以考出联赛分数,%%%. 下面放解题报告.并不喜 ...

  8. BZOJ:4816: [Sdoi2017]数字表格

    4816: [Sdoi2017]数字表格 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 501  Solved: 222[Submit][Status ...

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

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

随机推荐

  1. Mongodb compass 介绍

    参考官方文档:https://docs.mongodb.com/compass/current/install/#install-on-red-hat-enterprise-linux-rhel Mo ...

  2. beta阶段成果展示博客

    跟着我们一一点一点揭开蒙娜丽莎的微笑 - 本次beta阶段之前,我们团队,对其他组在事后诸葛亮期间对我们的评价进行深刻的审视,特别是缺点方面,开了好几次的站立会议,专门讨论beta的主要方向和任务.最 ...

  3. Appium 服务关键字(转)

    来源: https://github.com/appium/appium/blob/master/docs/cn/writing-running-appium/caps.cn.md#appium-服务 ...

  4. 在MFC中显示图片(opencv Mat类型)

    1,在MFC窗体中添加picture control控件,并添加对应的变量名 2,在窗体的初始化窗口中添加: namedWindow(); HWND hWnd = (HWND)cvGetWindowH ...

  5. JVM 规范

    http://files.cnblogs.com/files/dragonsuc/jls8.pdf 或者官网:http://files.cnblogs.com/files/dragonsuc/jls8 ...

  6. 【移动端debug-4】iOS下setTimeout无法触发focus事件的解决方案

    开篇总结:其实目前无法解决这个bug. 这两天做项目遇到了这个case,项目需求是打开页面的时候,input元素自动弹起键盘.由于各种方面的考虑,我们希望通过setTimeout延时200毫秒让inp ...

  7. MySQL 5.6 & 5.7最优配置文件模板

    Inside君整理了一份最新基于MySQL 5.6和5.7的配置文件模板,基本上可以说覆盖90%的调优选项,用户只需根据自己的服务器配置稍作修改即可,如InnoDB缓冲池的大小.IO能力(innodb ...

  8. ajax发送post请求遇到的坑

    前端小白的我. 用django-rest-framework写好了一个接口.如下,就接收两个字符串参数. 前端写了一个简单的提交post请求到这个接口,如下 浏览器提交请求后,一直提示 400 Bad ...

  9. python参数传递方式

    原文地址:http://www.cnblogs.com/zhaopengcheng/p/5492183.html python中一切皆对象,函数中参数传递的是对象的引用. 1在函数中改变变量指向的对象 ...

  10. dp的一些计划

    抱歉这是鸽子贴. 树形dp [x][[POI2014]HOT-Hotels](https://www.luogu.org/problemnew/show/P3565) [x][[HAOI2015]树上 ...