数字表格

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. Mysql 工作原理

    刚开始接触一个新的事物的时候,我觉得很有必要从其工作原理入手,弄清楚这个东西的来龙去脉,为接下来的继续深入学习做好铺垫,掌握好其原理有助于我们从整体上来把握这个东西,并且帮助我们在排错过程中理清思路. ...

  2. 导弹拦截与Dilworth定理

    这两天被Dilworth.链和反链搞到头昏脑胀,终于有点眉目,现在来总结一下. Dilworth定理说的是:对于一个偏序集,其最少链划分数等于其最长反链的长度. Dilworth定理的对偶定理说的是: ...

  3. s3c2440调试nandflash裸机程序遇到的问题

    图挂了可以去 https://github.com/tanghammer/mini2440_peripherals/blob/master/nand/debug_nand.md 按照前面sdram的代 ...

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

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

  5. 3ds Max学习日记(三)

      今天把第三章搞完了,学的是样条线(splines)建模的一些操作.不过实习又有新任务了,得去研究一下如何将单张图片转化为三维模型(我擦,这神马操作),所以可能没有那么多时间愉快地与3ds max玩 ...

  6. YaoLingJump开发者日志(六)

      作为一只天才魔法少女狐,不会魔法怎么行?于是我给瑶玲增加了一个技能:魔法弹.   当然,能使用魔法的前提是得有个魔杖,像这样:   魔杖不仅能让瑶玲使用魔法,当瑶玲被攻击时还能提供2s的无敌状态: ...

  7. thinkphp5 隐藏入口和支持pathinfo

    url里public目录的隐藏 其实正常思路的话这个url里的public本身就是不存在的,然后呢,其实也不叫隐藏public目录,这里只是考虑到有些童鞋可能还会按之前3.x时代的习惯来配置网站根目录 ...

  8. java中sql语句能不能加分号的问题?

    一.原因  在程序运行中,当执行sql后总是报无效字符错误:但是把程序放在pl/sql中执行又没有错误.让我很纳闷!于是我开始查找资料,然后我终于发现了问题. 二.问题剖析 原来在程序中:如果你在程序 ...

  9. Windows7系统目录迁移:Users,Progr…

    微软设计了比如:我的文档.我的OOXX,之类的东西,在WIN7下面更连游戏.下载等等目录都设计好了,我也很乖巧的把各种文件都分门别类的放进去了. 同时也很厉害的设计在了“%HOMEDRIVE%”里面, ...

  10. SpringBoot2.0(二) 配置文件多环境

    在SpringBoot中,多环节的配置文件名基于application-{profile}.properties的格式,其中{profile}对应环境标识,比如: application-daily. ...