数字表格

Time Limit: 50 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

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

Output

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

Sample Input

  3
  2 3
  4 5
  6 7

Sample Output

  1
  6
  960

HINT

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

Solution

  运用莫比乌斯反演,得到式子:

  这样我们对于内外分块即可,复杂度为O(n^(0.75)*T)。

  然后我们会发现在BZOJ上过不去,怎么办呢?卡常!BearChild运用了如下的卡常技巧:

    1.  读入优化; 2. O(n)预处理逆元; 3. 内嵌汇编实现乘和取模; 4. 记录n/i,避免多次除法。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE = 1e6+;
const int MOD = 1e9+;
const int PHI = 1e9+; int T;
int n,m;
int prime[ONE],p_num,miu[ONE];
int F[ONE];
bool isp[ONE];
s64 Ans; int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int Quickpow(int a,int b)
{
int res = ;
while(b)
{
if(b&) res = (s64)res*a%MOD;
a = (s64)a*a%MOD;
b>>=;
}
return res;
} void Deal_first(int MaxN)
{
F[]=;
F[]=; for(int i=; i<=MaxN; i++) F[i] = ((s64)F[i-]+F[i-]) % MOD;
F[]=; for(int i=; i<=MaxN; i++) F[i] = (s64)F[i]*F[i-] % MOD; miu[] = ;
for(int i=; i<=MaxN; i++)
{
if(!isp[i])
prime[++p_num] = i, miu[i] = -;
for(int j=; j<=p_num, i*prime[j]<=MaxN; j++)
{
isp[i * prime[j]] = ;
if(i % prime[j] == )
{
miu[i * prime[j]] = ;
break;
}
miu[i * prime[j]] = -miu[i];
}
miu[i] += miu[i-];
}
} int f(int n,int m)
{
if(n > m) swap(n,m);
s64 Ans = ;
for(int i=,j=; i<=n; i=j+)
{
j = min(n/(n/i), m/(m/i));
Ans += (s64)(n/i) * (m/i)%PHI * ((s64)(miu[j] - miu[i-] + PHI)%PHI) % PHI;
Ans %= PHI;
}
return Ans;
} void Solve()
{
n=get(); m=get();
if(n > m) swap(n,m);
Ans = ;
for(int i=,j=; i<=n; i=j+)
{
j = min(n/(n/i), m/(m/i));
Ans = Ans * Quickpow( (s64)F[j] * Quickpow(F[i-],MOD-) % MOD , f(n/i,m/i) % PHI) % MOD;
}
printf("%lld\n",Ans);
} int main()
{
Deal_first(ONE-);
T = get();
while(T--)
Solve();
return ;
}

非卡常版

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE = 1e6+;
const int MOD = 1e9+;
const int PHI = 1e9+; int T;
int n,m;
int prime[ONE],p_num,miu[ONE];
int Niyu[ONE];
int F[ONE];
bool isp[ONE];
int Ans; inline int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} inline int modmul(const int &a, const int &b,const int &M)
{
int ret;
__asm__ __volatile__("\tmull %%ebx\n\tdivl %%ecx\n" : "=d"(ret) : "a"(a), "b"(b), "c"(M));
return ret;
} inline int Quickpow(int a,int b)
{
int res = ;
while(b)
{
if(b&) res = modmul(res,a,MOD);
a = modmul(a,a,MOD);
b>>=;
}
return res;
} inline void Deal_first(int MaxN)
{
F[]=; F[]=;
int val=;
for(int i=; i<=MaxN; i++)
{
F[i] = F[i-]+F[i-];
if(F[i] >= MOD) F[i] -= MOD;
val = modmul(val,F[i],MOD);
}
Niyu[MaxN] = Quickpow(val, MOD-);
for(int i=MaxN-;i>=;i--) Niyu[i] = modmul(Niyu[i+],F[i+],MOD);
Niyu[] = Niyu[]; F[]=;
for(int i=; i<=MaxN; i++) F[i] = modmul(F[i],F[i-],MOD); miu[] = ;
for(int i=; i<=MaxN; i++)
{
if(!isp[i])
prime[++p_num] = i, miu[i] = -;
for(int j=; j<=p_num, i*prime[j]<=MaxN; j++)
{
isp[i * prime[j]] = ;
if(i % prime[j] == )
{
miu[i * prime[j]] = ;
break;
}
miu[i * prime[j]] = -miu[i];
}
miu[i] += miu[i-];
}
} inline int f(int n,int m)
{
if(n > m) swap(n,m);
int Ans = ;
for(int i=,j=; i<=n; i=j+)
{
int x=n/i, y=m/i;
j = min(n/x, m/y);
Ans = ((s64)Ans + modmul(modmul(x,y,PHI) , ((s64)miu[j] - miu[i-] + PHI), PHI) )%PHI;
}
return Ans;
} inline void Solve()
{
n=get(); m=get();
if(n > m) swap(n,m);
Ans = ;
for(int i=,j=; i<=n; i=j+)
{
int x=n/i, y=m/i;
j = min(n/x, m/y);
Ans = (s64)modmul(Ans , Quickpow( modmul(F[j],Niyu[i-],MOD) , f(x,y)), MOD);
}
printf("%d\n",Ans);
} int main()
{
Deal_first(ONE-);
T = get();
while(T--)
Solve();
return ;
}

卡常版

【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 ...

随机推荐

  1. 2019寒假训练营寒假作业(三) 对Sketch——CM-Sketch的理解(理论题部分)

    目录 实验题部分 基本题 1.简述sketch: 2.Count-min Sketch: 开放题部分 理论部分 1.解释为什么 sketch 可以省空间 2.用流程图描述Count-min sketc ...

  2. servlet映射路径

    1 访问映射过程 问题:访问URL:http://localhost:8080/day10/first  ,服务器如何相应的? 前提: tomcat服务器启动时,首先加载webapps中的每个web应 ...

  3. Java之I/O流(第1部分)

    Java 中的I/O流: 1. 输入/输出流原理: 如下图所示:在 java 程序中,对于数据的输入/输出操作以“流”(Stream)的方式进行:J2SDK 提供了各种各样的“流”类,用来获取不同种类 ...

  4. css那些事儿4 背景图像

    background:背景颜色,图像,平铺方式,大小,位置 能够显示背景区域即为盒子模型的填充和内容部分,其中背景图像将会覆盖背景颜色.常见的水平或垂直渐变颜色背景通常使用水平或垂直渐变的背景图像在水 ...

  5. 3dContactPointAnnotationTool开发日志(二十)

      为了使工具更人性化,我又在每个status的text上绑了个可以拖拽实现值改变的脚本,但是不知道为啥rotx那个值越过+-90范围后连续修改就会产生抖动的现象,试了很多方法也没能弄好,不过实际用起 ...

  6. HDU 2161 Primes

    http://acm.hdu.edu.cn/showproblem.php?pid=2161 Problem Description Write a program to read in a list ...

  7. 查询MySQL某字段相同值得重复数据

    1.先查询重复的id: SELECT book_id,COUNT(*) AS COUNT FROM xs_book_source WHERE site_id=5 GROUP BY book_id HA ...

  8. IPython 4.0发布:Jupyter和IPython分离后的首个版本

    IPython 4.0日前正式发布,这是IPython分离成IPython和Jupyter后的第一个重要版本. 更新Jupyter的快捷方式是: pip install --upgrade jupyt ...

  9. UDP发送的数据 以数据包形式发送

    UDP发送的数据 以数据包形式发送

  10. BZOJ2458:[BJOI2011]最小三角形——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2458 Description Xaviera现在遇到了一个有趣的问题. 平面上有N个点,Xavier ...