BZOJ4816 [Sdoi2017]数字表格 数论 莫比乌斯反演
原文链接http://www.cnblogs.com/zhouzhendong/p/8666106.html
题目传送门 - BZOJ4816
题意
定义$f(0)=0,f(1)=1,f(i)=f(i-1)+f(i-2)$。
$T$组数据,每组数据两个整数$n,m$,求$\prod_{i=1}^n\prod_{j=1}^m f(\gcd(i,j))$。
$T\leq 1000,1\leq n,m \leq 10^6$
题解
先推一波式子。
$$\prod_{i=1}^n\prod_{j=1}^m f(\gcd(i,j))\\=\prod_{d=1}^n f(d)^{\sum_{i=1}^{\left\lfloor\frac nd\right\rfloor}\sum_{j=1}^{\left\lfloor\frac md\right\rfloor}[\gcd(i,j)=1]}\\=\prod_{d=1}^n f(d)^{\sum_{i=1}^{\left\lfloor\frac nd\right\rfloor}\sum_{j=1}^{\left\lfloor\frac md\right\rfloor}\sum_{p|i,p|j}\mu(p)}\\=\prod_{d=1}^n f(d)^{\sum_{p=1}^{\left\lfloor\frac nd\right\rfloor}\mu(p)\left\lfloor\frac{n}{pd}\right\rfloor\left\lfloor\frac{m}{pd}\right\rfloor}$$
设$D=pd$。
$$\prod_{i=1}^n\prod_{j=1}^m f(\gcd(i,j))\\=\prod_{d=1}^n f(d)^{\sum_{p=1}^{\left\lfloor\frac nd\right\rfloor}\mu(p)\left\lfloor\frac{n}{pd}\right\rfloor\left\lfloor\frac{m}{pd}\right\rfloor}\\=\prod_{D=1}^{n}(\prod_{d|D}f(d)^{\mu(\frac Dd)})^{\left\lfloor\frac nD\right\rfloor\left\lfloor\frac mD\right\rfloor}$$
先顺手预处理$\mu$。
于是我们先预处理$f(x)$以及$f(x)$的逆元,然后再$O(n \log n)$预处理出所有$g(D)=\prod_{d|D}f(d)^{\mu(\frac Dd)}$。
然后再预处理出$g$的前缀积以及前缀积的逆元。
这些的复杂度都是$O(n \log n)$。
然后回答一个询问的时候再整除分块一下,单次询问复杂度为$O(\sqrt n \log n)$。
所以总复杂度为$O(n \log n+T\sqrt n \log n)$。
所有测试点的总时限开了50s。
哈哈应该稳过了吧!
但是!!!!!!
BZOJ毒!瘤!卡!常!!!!!!
于是我们需要常数优化。
考虑处理一个序列的逆元。
我们求出当前序列的前缀积是$O(n)$的。
记$a$为原序列。
记$inv_i$为的$i$项的逆元。
记$presum_i$为序列前$i$项的前缀积。
记$preinv_i$为序列钱$i$项的前缀积的逆元。
则:
$$inv_i=preinv_i\times presum_{i-1}$$
$$preinv_{i-1}=preinv_i\times a_i$$
于是你就可以倒着来求逆元了,复杂度$O(n)$。
但是求$g$的时候复杂度还是$O(n \log n)$。
所以总的复杂度还是$O(n \log n+T\sqrt n \log n)$。
但是你卡常数了!!!
你过了!!!
QAQ
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+5,mod=1e9+7;
LL prime[N],u[N],pcnt;
bool isprime[N];
LL f[N],pref[N],invf[N],g[N],preg[N],invg[N];
int T,n,m;
LL Pow(LL a,LL b){
if (!b)
return 1LL;
LL x=Pow(a,b/2);
x=x*x%mod;
if (b&1LL)
x=x*a%mod;
return x;
}
LL Inv(LL a){
return Pow(a,mod-2);
}
void get_prime(int n){
memset(isprime,true,sizeof isprime);
u[1]=1,pcnt=isprime[0]=isprime[1]=0;
for (int i=2;i<=n;i++){
if (isprime[i])
prime[++pcnt]=i,u[i]=-1;
for (int j=1;j<=pcnt&&i*prime[j]<=n;j++){
isprime[i*prime[j]]=0;
if (i%prime[j])
u[i*prime[j]]=-u[i];
else {
u[i*prime[j]]=0;
break;
}
}
}
}
void init(int n){
get_prime(n);
f[0]=0,f[1]=invf[1]=g[0]=1;
for (int i=2;i<=n;i++)
f[i]=(f[i-1]+f[i-2])%mod;
pref[0]=1;
for (int i=1;i<=n;i++)
pref[i]=pref[i-1]*f[i]%mod;
LL v=Inv(pref[n]);
for (int i=n;i>=1;i--)
invf[i]=v*pref[i-1]%mod,v=v*f[i]%mod;
for (int i=1;i<=n;i++)
g[i]=1;
for (int i=1;i<=n;i++)
for (int j=1;i*j<=n;j++){
if (u[j]==-1)
g[i*j]=g[i*j]*invf[i]%mod;
if (u[j]==1)
g[i*j]=g[i*j]*f[i]%mod;
}
preg[0]=1;
for (int i=1;i<=n;i++)
preg[i]=preg[i-1]*g[i]%mod;
invg[n]=Inv(preg[n]);
for (int i=n-1;i>=0;i--)
invg[i]=invg[i+1]*g[i+1]%mod;
}
int main(){
init(1e6);
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);
if (n>m)
swap(n,m);
LL ans=1;
for (int D=1,i;D<=n;D=i+1){
i=min(n/(n/D),m/(m/D));
ans=ans*Pow(preg[i]*invg[D-1]%mod,1LL*(n/D)*(m/D)%(mod-1))%mod;
}
printf("%lld\n",ans);
}
return 0;
}
BZOJ4816 [Sdoi2017]数字表格 数论 莫比乌斯反演的更多相关文章
- 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】数字表格(莫比乌斯反演)
[BZOJ4816]数字表格(莫比乌斯反演) 题面 BZOJ 求 \[\prod_{i=1}^n\prod_{j=1}^mf[gcd(i,j)]\] 题解 忽然不知道这个要怎么表示... 就写成这样吧 ...
- 洛谷3704 [SDOI2017] 数字表格 【莫比乌斯反演】
题目分析: 比较有意思,但是套路的数学题. 题目要求$ \prod_{i=1}^{n} \prod_{j=1}^{m}Fib(gcd(i,j)) $. 注意到$ gcd(i,j) $有大量重复,采用莫 ...
- bzoj 4816: [Sdoi2017]数字表格【莫比乌斯反演+逆元】
把题意简化,就是要求 \[ \prod_{d=1}^{min(n,m)}f[d]^{\sum_{i=1}^{n}\sum_{j=1}^{m}e[gcd(i,j)==d]} \] 把幂用莫比乌斯反演转化 ...
- 【BZOJ4816】[SDOI2017] 数字表格(莫比乌斯反演)
点此看题面 大致题意: 求\(\prod_{i=1}^n\prod_{j=1}^mf(gcd(i,j))\). 推式子 首先,按照套路我们枚举\(gcd\),得到: \[\prod_{d=1}^{mi ...
- P3704 [SDOI2017]数字表格 (莫比乌斯反演)
[题目链接] https://www.luogu.org/problemnew/show/P3704 [题解] https://www.luogu.org/blog/cjyyb/solution-p3 ...
- BZOJ 4816[SDOI2017]数字表格(莫比乌斯反演)
题目链接 \(Description\) 用\(f_i\)表示\(fibonacci\)数列第\(i\)项,求\(\prod_{i=1}^{n}\prod_{j=1}^{m}f[gcd(i,j)]\) ...
- [SDOI2017]数字表格 (莫比乌斯反演)
链接:https://ac.nowcoder.com/acm/problem/20391来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- 洛谷P3704 [SDOI2017]数字表格(莫比乌斯反演)
传送门 yyb大佬太强啦…… 感觉还是有一点地方没有搞懂orz //minamoto #include<cstdio> #include<iostream> #include& ...
随机推荐
- Maven安装与配置及使用
下载及安装 官方下载地址:直达官网下载页面 进入下载页面后,根据你电脑所装jdk版本选择对应版本的maven进行下载. 我们可以看到该页上边红框内写明了,maven3.3版以上支持的是JDK1.7+的 ...
- Laravel 5.2--改变数据库字段值,编辑时候,默认选中
模型 <?php namespace App\Models; use App\Helpers\ImageHelper; use App\Libraries\Nestedset\NodeTrait ...
- Hive学习01-基础常见问题
理论: 什么是hive: 1. Hive旨在实现轻松的数据汇总,即时查询和分析大量数据. 2. 它提供了SQL,使用户可以轻松地进行临时查询,汇总和数据分析. 3. Hive可以使用用户定义函数( ...
- Java位运算符浅析
在学习源码中,发现有大量使用位运算符,这样做的目的是为了节约内存开销和加快计算效率. 位运算符,这个”位”代表这什么? 位:二进制位简称“位”,是二进制记数系统中表示小于2的整数的符号,一般用1或 0 ...
- 【sqli-labs】Less17
Less17: POST注入,UPDATE语句,有错误回显 新知识点: 1. update注入方法 参考:http://www.mamicode.com/info-detail-1665678.htm ...
- 表达式语言 Expression Language
JSP 2.0最重要的特性之一就是表达式语言 (EL),JSP用户可以用它来访问应用程序数据.由于 受到ECMAScript和XPath表达式语言的启发,EL也设计 成可以轻松地编写免脚本的JSP页面 ...
- cf1110d 线性dp
很精练的一道题 /* dp[i][j][k]表示值i作为最大值结束的边剩k条,i-1剩下j条的情况的结果 dp[i][k][l]是由dp[i-1][j][k]的j决定的,因为k+l是被留下给后面用的, ...
- hdu3586 树形dp+二分答案
/* dp[i]表示孤立i结点的费用,二分功率上限w,即dp[i]在选择时不可以选择功率大于w的边 */ #include<bits/stdc++.h> using namespace s ...
- jenkins持续集成:jenkins+SVN
实现jenkins从svn拉取最新的代码,再执行驱动脚本进行自动化测试 新建一个任务 输入任务名,选“构建一个自由风格的软件项目”,点左下角“确定” 丢弃旧的构建,如下设置为保留3天内的10条构建记录 ...
- vue-cli3.0 使用postcss-plugin-px2rem(推荐)和 postcss-pxtorem(postcss-px2rem)自动转换px为rem 的配置方法;
如何在vue-cli3.0中使用postcss-plugin-px2rem 插件 插件的作用是 自动将vue项目中的px转换为rem . 为什么这三个中要推荐 postcss-plugin-px2r ...