【BZOJ4816】【SDOI2017】数字表格 [莫比乌斯反演]
数字表格
Time Limit: 50 Sec Memory Limit: 128 MB
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
2 3
4 5
6 7
Sample Output
6
960
HINT
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】数字表格 [莫比乌斯反演]的更多相关文章
- BZOJ4816 SDOI2017 数字表格 莫比乌斯反演
传送门 做莫比乌斯反演题显著提高了我的\(\LaTeX\)水平 推式子(默认\(N \leq M\),分数下取整,会省略大部分过程) \(\begin{align*} \prod\limits_{i= ...
- [Sdoi2017]数字表格 [莫比乌斯反演]
[Sdoi2017]数字表格 题意:求 \[ \prod_{i=1}^n \prod_{j=1}^m f[(i,j)] \] 考场60分 其实多推一步就推倒了... 因为是乘,我们可以放到幂上 \[ ...
- 【bzoj4816】[Sdoi2017]数字表格 莫比乌斯反演
题目描述 Doris刚刚学习了fibonacci数列.用f[i]表示数列的第i项,那么 f[0]=0 f[1]=1 f[n]=f[n-1]+f[n-2],n>=2 Doris用老师的超级计算机生 ...
- [bzoj4816][Sdoi2017]数字表格 (反演+逆元)
(真不想做莫比乌斯了) 首先根据题意写出式子 ∏(i=1~n)∏(j=1~m)f[gcd(i,j)] 很明显的f可以预处理出来,解决 根据套路分析,我们可以先枚举gcd(i,j)==d ∏(d=1~n ...
- BZOJ.4816.[SDOI2017]数字表格(莫比乌斯反演)
题目链接 总感觉博客园的\(Markdown\)很..\(gouzhi\),可以看这的. 这个好像简单些啊,只要不犯sb错误 [Update] 真的算反演中比较裸的题了... \(Descriptio ...
- BZOJ 4816 [Sdoi2017]数字表格 ——莫比乌斯反演
大力反演出奇迹. 然后xjb维护. 毕竟T1 #include <map> #include <ctime> #include <cmath> #include & ...
- 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)}\),多组询问, ...
- [BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块)
[BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块) 题面 求 \[\sum_{i=1}^{n} \sum_{j=1}^{m} \mathrm{lcm}(i,j)\] 分析 \[\su ...
- [SDOI2017]数字表格 --- 套路反演
[SDOI2017]数字表格 由于使用markdown的关系 我无法很好的掌控格式,见谅 对于这么简单的一道题竟然能在洛谷混到黑,我感到无语 \[\begin{align*} \prod\limits ...
随机推荐
- Java数组课程作业
设计思路:生成随机数,赋值给数组.再将其求和输出 程序流程图: 源程序代码: import javax.swing.JOptionPane; public class Test { public st ...
- 用纯css改变下拉列表select框的默认样式(转)
用纯css改变下拉列表select框的默认样式 分享到 分类 JS学习 关键字 前端 发布 kris 2015-04-01 注意 转载须保留原文链接,译文链接,作者译者等信息. 在这 ...
- OSG学习:多重纹理映射
#include<osgViewer\Viewer> #include<osg\Node> #include<osg\Geode> #include<osg\ ...
- 《学习OpenCV》课后习题解答1
题目:(P104) 下面这个练习是帮助掌握矩阵类型.创造一个三通道二维矩阵,字节类型,大小为100*100,并设置所有数值为0. a.在矩阵中使用cvCircle( CvArr* img, CvPoi ...
- python爬虫从入门到放弃(五)之 正则的基本使用(转)
什么是正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是 事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符”,这个“规则字符” 来表达对字符的一种过滤逻辑. 正则并不是pyth ...
- Java取两个变量不为空的变量的简便方法!
一.需求 最近在项目中遇到一个小问题,即从数据库取两个变量,判断取出的变量是否为空,取不为空的变量:若两个变量都不为空,取两个变量:两个变量都为空,则跳过: 二.解决方案(这里提供两种思路) 1.第一 ...
- 第一篇:python基础_1
本篇内容 Python介绍 安装 第一个程序(hello,world) 变量 用户输入(input) 数据类型 数据运算 if判断 break和continue的区别 while 循环 一. Pyth ...
- jzoj3865[JSOI2014]士兵部署
‘ 数据范围:n,m<=10^5,传送门:https://jzoj.net/senior/#main/show/3865 感觉jzoj好高明啊,就是访问不太稳定. 首先题意中被n个点控制的区域相 ...
- vdbench和fio测试磁盘性能的对比总结
一.安装 1.安装vdbench,首先安装java:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213 ...
- Linux(ubuntu 12.04桌面版) 搭建Android开发环境
因为一些工作上的原因,需要切换到Linux环境下做点开发,我选择的Linux发行版本为ubuntu(我不建议使用fedora,我最开始就是使用的fedora,但发现并不是特别好使,有些插件没办法安装, ...