【JZOJ6150】爱乐之城
Description
给定
n
n
n个元素
a
1
∼
n
a_{1∼n}
a1∼n,对于
i
∈
[
1
,
n
]
i \in[1,n]
i∈[1,n]求
F
(
a
1
∼
i
)
F(a_{1∼i})
F(a1∼i)。
其中:
f
(
n
)
=
∑
i
=
1
n
∑
j
=
1
n
μ
(
i
j
)
f(n)=\sum_{i=1}^n\sum_{j=1}^n\mu(ij)
f(n)=∑i=1n∑j=1nμ(ij)
g
(
n
)
=
∑
i
=
1
n
i
∑
j
=
1
n
[
g
c
d
(
i
,
j
)
=
1
]
j
g(n)=\sum_{i=1}^n i\sum_{j=1}^n[gcd(i,j)=1]j
g(n)=∑i=1ni∑j=1n[gcd(i,j)=1]j
F
(
S
)
=
∑
T
∈
S
f
(
g
c
d
(
a
∈
T
)
)
∏
a
∈
T
g
(
a
)
F(S)=\sum_{T\in S}f(gcd(a\in T))\prod_{a\in T}g(a)
F(S)=∑T∈Sf(gcd(a∈T))∏a∈Tg(a)
答案对998244353取模,强制在线,真实的
a
i
a_i
ai两两不同。
Solution
以下n非题目中的n
g
(
n
)
=
2
(
∑
i
=
2
n
i
∑
j
=
1
i
[
g
c
d
(
i
,
j
)
=
1
]
j
)
+
1
=
∑
i
=
1
n
i
2
φ
(
i
)
g(n)=2(\sum_{i=2}^ni\sum_{j=1}^i[gcd(i,j)=1]j)+1=\sum_{i=1}^ni^2φ(i)
g(n)=2(∑i=2ni∑j=1i[gcd(i,j)=1]j)+1=∑i=1ni2φ(i)
f
(
n
)
=
∑
i
=
1
n
μ
(
i
)
∑
j
=
1
⌊
n
i
⌋
∑
k
=
1
⌊
n
i
⌋
μ
(
i
j
)
μ
(
i
k
)
=
∑
i
=
1
n
μ
(
i
)
(
∑
j
=
1
⌊
n
i
⌋
μ
(
j
k
)
)
2
f(n)=\sum_{i=1}^n\mu(i)\sum_{j=1}^{\lfloor\frac{n}{i}\rfloor}\sum_{k=1}^{\lfloor\frac{n}{i}\rfloor}\mu(ij)\mu(ik)=\sum_{i=1}^n\mu(i)(\sum_{j=1}^{\lfloor\frac{n}{i}\rfloor}\mu(jk))^2
f(n)=∑i=1nμ(i)∑j=1⌊in⌋∑k=1⌊in⌋μ(ij)μ(ik)=∑i=1nμ(i)(∑j=1⌊in⌋μ(jk))2
注意到我们要对
f
(
1
∼
m
)
f(1∼m)
f(1∼m)都求答案,但
n
n
n每增加
1
1
1改动只有约数个数位,所以增量求即可。
构造函数
h
(
n
)
h(n)
h(n)使得
f
(
n
)
=
∑
d
∣
n
h
(
d
)
f(n)=\sum_{d|n}h(d)
f(n)=∑d∣nh(d),即
h
(
n
)
=
f
(
n
)
−
∑
d
∣
n
&
d
<
n
h
(
d
)
h(n)=f(n)-\sum_{d|n\&d<n}h(d)
h(n)=f(n)−∑d∣n&d<nh(d)。
那么
F
(
S
)
=
∑
T
∈
S
(
∑
d
∣
g
c
d
(
a
∈
T
)
h
(
d
)
)
∏
a
∈
T
g
(
a
)
F(S)=\sum_{T\in S}(\sum_{d|gcd(a\in T)}h(d))\prod_{a\in T}g(a)
F(S)=∑T∈S(∑d∣gcd(a∈T)h(d))∏a∈Tg(a)
交换主体:
F
(
S
)
=
∑
d
=
1
m
h
(
d
)
(
∏
d
∣
a
(
g
(
a
)
+
1
)
−
1
)
F(S)=\sum_{d=1}^m h(d)(\prod_{d|a}(g(a)+1)-1)
F(S)=∑d=1mh(d)(∏d∣a(g(a)+1)−1)
注意到
F
(
S
)
F(S)
F(S)增加一位也只会改变约数个数的值,且
a
i
a_i
ai两两不同,直接算即可。
Code
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#define fo(i,j,k) for(int i=j,o=k;i<=o;++i)
#define fd(i,j,k) for(int i=j;i>=k;--i)
using namespace std;
typedef long long ll;
const int N=4e5+10,mo=998244353;
int mu[N],pr[N],phi[N];
vector<int> b[N];
int read(){
char ch=' ';int t=0;
for(;ch<'0' || ch>'9';ch=getchar());
for(;ch>='0' && ch<='9';ch=getchar()) t=(t<<1)+(t<<3)+ch-48;
return t;
}
int pl(int x,int y){
return x+y>=mo?x+y-mo:x+y;
}
void inc(int &x,int y){
x=x+y>=mo?x+y-mo:x+y;
}
void pre(int n){
mu[1]=phi[1]=1;
fo(i,2,n){
if(!phi[i]) phi[i]=i-1,mu[i]=-1,pr[++pr[0]]=i;
fo(j,1,pr[0]){
int t=i*pr[j];
if(t>n) break;
if(i%pr[j]==0) {phi[t]=phi[i]*pr[j],mu[t]=0;break;}
mu[t]=-mu[i],phi[t]=phi[i]*(pr[j]-1);
}
}
}
int f[N],g[N],s[N],h[N],w[N];
int main()
{
freopen("lalaland.in","r",stdin);
freopen("lalaland.out","w",stdout);
int n=read(),m=read(),tp=read();
pre(m);
fo(i,1,m) g[i]=pl(g[i-1],(ll)i*i%mo*phi[i]%mo);
fo(i,1,m)
fo(j,1,m/i) b[i*j].push_back(i);
fo(i,1,m){
f[i]=f[i-1];
for(int d:b[i]){
int t=mu[i]*(2*s[d]+mu[i]);
f[i]+=mu[d]*t%mo;
s[d]+=mu[i];
}
}
fo(i,1,m){
h[i]=f[i];
for(int d:b[i]) if(d<i) h[i]-=h[d];
}
fo(i,1,m) h[i]=(h[i]+mo)%mo,w[i]=1;
int ans=0;
fo(i,1,n){
int x=read();
if(tp==1) x=(19891989ll*ans+x)%m+1;
for(int d:b[x]){
inc(ans,mo-(ll)h[d]*(w[d]-1)%mo);
w[d]=(ll)w[d]*pl(g[x],1)%mo;
inc(ans,(ll)h[d]*(w[d]-1)%mo);
}
if(tp) printf("%d\n",ans);
}
if(!tp) printf("%d\n",ans);
}