luoguP5221 Product
Product
题目背景
\({\rm CYJian}\):"听说\(gcd\)和\(\sum\)套起来比较好玩??那我就......"
题目描述
\({\rm CYJian}\)最近闲的玩起了\(gcd\)。。他想到了一个非常简单而有意思的式子:
\({\rm CYJian}\)已经算出来这个式子的值了。现在请你帮他验算一下吧。\({\rm CYJian}\)只给你\(0.2s\)的时间哦。
2024.5.11 upd: 放宽时空限制。
输入格式
一行一个正整数\(N\)。
输出格式
一行一个正整数,表示答案模\(104857601\)的值。
样例 #1
样例输入 #1
5
样例输出 #1
585494
提示
样例解释:
\(\frac{lcm}{gcd}\) | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
1 | 1 | 2 | 3 | 4 | 5 |
2 | 2 | 1 | 6 | 2 | 10 |
3 | 3 | 6 | 1 | 12 | 15 |
4 | 4 | 2 | 12 | 1 | 20 |
5 | 5 | 10 | 15 | 20 | 1 |
对于\(30\%\)的数据:\(1 \leq N \leq 5000\)
对于\(100\%\)的数据:\(1 \leq N \leq 1000000\)
原式\(=\displaystyle\prod_{i=1}^{n}\displaystyle\prod_{j=1}^{n}\frac{i*j}{gcd(i,j)^2}\)
直接拆开,由于是乘法不是加法,算了两部分直接成绩来即可
原式\(=(\displaystyle\prod_{i=1}^{n}\displaystyle\prod_{j=1}^{n}{i*j})\times(\displaystyle\prod_{i=1}^{n}\displaystyle\prod_{j=1}^{n}\frac{1}{gcd(i,j)^2})\)
前面的部分明显很好算,看看后面的部分。
\((\displaystyle\prod_{i=1}^{n}\displaystyle\prod_{j=1}^ngcd(i,j))^{-2}\),只需要考虑里面的部分怎么搞。
\(\displaystyle\prod_{i=1}^{n}\displaystyle\prod_{j=1}^ngcd(i,j)\)经典反演套路,枚举\(d=gcd(i,j)\)并且提前,得到原式\(=\displaystyle\prod_d^{n}d^{\displaystyle\sum_{i=1}^{n}\displaystyle\sum_{j=1}^{n}[gcd(i,j)=d]}\)
那其实要算的就变成了\(\displaystyle\sum_{i=1}^{n}\displaystyle\sum_{j=1}^{n}[gcd(i,j)=d]\)
莫反板子题吧
还是写完吧,好分析复杂度。
\(\displaystyle\sum_{i=1}^{n}\displaystyle\sum_{j=1}^{n}[gcd(i,j)=d]\\
= \displaystyle\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\displaystyle\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}[gcd(i,j)=1]\)
\([gcd(i,j)=1]=\displaystyle\sum_{e|gcd(i,j)}\mu(e)\),上式变为\(\displaystyle\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\displaystyle\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}\displaystyle\sum_{e|gcd(i,j)}\mu(e)\)
\(e\)提前,变为\(\displaystyle\sum_{e=1}^{\lfloor\frac nd\rfloor}\mu(e)\displaystyle\sum_{i=1}^{\lfloor\frac{n}{de}\rfloor}\displaystyle\sum_{j=1}^{\lfloor\frac{n}{de}\rfloor}=\displaystyle\sum_{e=1}^{\lfloor\frac nd\rfloor}\mu(e)\times\lfloor\frac n {de}\rfloor^2\)
后面的直接整除分块,这个式子是\(O(\sqrt n)\)的
然后算上枚举\(d\),\(O(n\sqrt n)\),\(n=1e6\)。。。
应该是前面的部分也整除分块计算,\(\displaystyle\prod_d^{n}{d^{\displaystyle\sum_{e=1}^{\lfloor\frac nd\rfloor}\mu(e)\times\lfloor\frac n {de}\rfloor^2}}\)
完全没法算啊。哦,直接算就好了。。。后面的循环是调和级数。疑似不用整除分块。。
再看看前面的部分,\(\displaystyle\prod_{i=1}^{n}\displaystyle\prod_{j=1}^{n}{i*j}\),很明显,这中间连一个加号都没有,顺序随便换。我们对于每个数字\(1\leq i\leq n\)考虑它出现过几次。
很容易发现是\(2\times n\)次,所以这个部分其实等于\({(n!)}^{{(2n)}}\)
那么便是结束了。
总体复杂度\(O(n\ln n)\)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=1e6+10;
const ll Mod=104857601;
inline ll read(){
ll a=0,b=1;char c=getchar();
for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
for(;c>='0'&&c<='9';c=getchar())a=a*10+c-'0';
return a*b;
}
ll n;
ll prim[N+1],cnt,vis[N+1],mu[N+1],phi[N+1];
void init()
{
mu[1]=phi[1]=1;//先用筛法算出较小的部分
for(ll i=2;i<=N;i++)
{
if(vis[i]==0)prim[++cnt]=i,mu[i]=-1,phi[i]=i-1;
for(ll j=1;j<=cnt&&prim[j]*i<=N;j++)
{
vis[prim[j]*i]=1;
if(i%prim[j]==0)
{
phi[i*prim[j]]=phi[i]*prim[j];
mu[i*prim[j]]=0;
break;
}
phi[i*prim[j]]=phi[i]*phi[prim[j]];
mu[i*prim[j]]=mu[i]*mu[prim[j]];
}
}
}
inline ll ksm(ll a,ll b)
{
ll r=1;
while(b)
{
// cout<<b<<' ';
if(b&1ll) r=1ll*r*a%Mod;
b>>=1;
a=1ll*a*a%Mod;
}
return r;
}
int main()
{
init();
n=read();
ll ans=1;
for(ll d=1;d<=n;d++)
{
ll ned=0;
for(ll e=1;e<=n/d;e++)
{
ned=(ned+mu[e]*(n/d/e)%(Mod-1)*(n/d/e)%(Mod-1)+(Mod-1))%(Mod-1);
}
ans=(ans*ksm(d,ned))%Mod;
}
ans=ksm(ans*ans%Mod,Mod-2);
for(ll i=1;i<=n;i++)
{
ans=(ans*ksm(i,2*n))%Mod;
}
cout<<ans<<endl;
return 0;
}
无敌了。。\(\mu_i\)是有可能为负数的,所以取模的时候一定要注意。。。
然后我特么的对着公式写代码写错了调了我两个小时没看出来???????????
我在玩原神吗。