题目
泰勒应天下大雨!
类似于
S
D
O
I
2018
SDOI2018
SDOI2018旧试题。
给
D
D
D,
E
E
E,
F
F
F卷上
μ
\mu
μ。
得到
D
′
,
E
′
,
F
′
D',E',F'
D′,E′,F′。
原式变为
∑
i
,
j
,
k
A
i
B
j
C
k
∑
a
∣
i
,
a
∣
j
D
a
′
∑
b
∣
i
,
b
∣
k
E
b
′
∑
c
∣
j
,
c
∣
k
F
c
′
\sum_{i,j,k} A_iB_jC_k \sum_{a|i,a|j} D'_a \sum_{b|i,b|k} E'_b \sum_{c|j,c|k} F'_c
i,j,k∑AiBjCka∣i,a∣j∑Da′b∣i,b∣k∑Eb′c∣j,c∣k∑Fc′
交换和号:
∑
a
,
b
,
c
D
a
′
E
b
′
F
c
′
∑
lcm
(
a
,
b
)
∣
i
,
lcm
(
a
,
c
)
∣
j
,
lcm
(
b
,
c
)
∣
k
A
i
,
B
j
,
C
k
\sum_{a,b,c} D'_aE'_bF'_c\sum_{\operatorname{lcm}(a,b)|i,\operatorname{lcm}(a,c)|j,\operatorname{lcm}(b,c)|k} A_i,B_j,C_k
a,b,c∑Da′Eb′Fc′lcm(a,b)∣i,lcm(a,c)∣j,lcm(b,c)∣k∑Ai,Bj,Ck
给
A
,
B
,
C
A,B,C
A,B,C做一个变换如括号中所述(
A
i
′
=
∑
i
∣
d
A
d
A'_i = \sum_{i|d} A_d
Ai′=∑i∣dAd)
得到
A
′
,
B
′
,
C
′
A',B',C'
A′,B′,C′。
则原式变为
∑
a
,
b
,
c
D
a
′
E
b
′
F
c
′
A
lcm
(
a
,
b
)
′
B
lcm
(
a
,
c
)
′
C
lcm
(
b
,
c
)
′
\sum_{a,b,c} D'_aE'_bF'_cA'_{\operatorname{lcm}(a,b)}B'_{\operatorname{lcm}(a,c)}C'_{\operatorname{lcm}(b,c)}
∑a,b,cDa′Eb′Fc′Alcm(a,b)′Blcm(a,c)′Clcm(b,c)′
所以我们就对于
lcm
a
,
b
≤
n
\operatorname{lcm}_{a,b} \leq n
lcma,b≤n的
a
,
b
a,b
a,b连边求三元环计数(注意这里是有边权有点权的三元环权值计数,权值为点权和边权六个的乘积。)
随便跑了一下最大数据发现有
m
=
2625630
m=2625630
m=2625630 条边。
写一个三元环计数即可在
O
(
m
m
)
O(m \sqrt m)
O(mm)的复杂度解决此题。
虽然和标程
n
n
log
log
n
n \sqrt n \log \log n
nnloglogn比起来感觉有点不优秀(
2
e
6
2e6
2e6的
m
m
m\sqrt m
mm也挺吓人的,本机不开
−
O
2
-O2
−O2跑了
10
s
10s
10s。)
但是在
L
O
J
LOJ
LOJ的实际表现是差不多的。
A
C
C
o
d
e
\mathcal AC \ Code
AC Code
#include<bits/stdc++.h>
#define maxn 100005
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
#define LL long long
#define pii pair<int,LL>
#define mp make_pair
#define vi vector<pair<int,LL> >
#define pb emplace_back
using namespace std;
char cb[1<<16],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<16,stdin),cs==ct)?0:*cs++)
template<class T>void read(T &res){
char ch;
for(;!isdigit(ch=getc()););
for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0');
}
int n,mu[maxn],pr[maxn],cnt_pr,vis[maxn],in[maxn];
LL A[6][maxn],B[6][maxn],ans;
int gcd(int a,int b){ return !b ? a : gcd(b,a%b); }
void upd(int a,int b,int c,int lab,int lbc,int lac){
ans +=
B[0][lab] * B[1][lac] * B[2][lbc] * B[3][a] * B[4][b] * B[5][c] +
(a != b ? B[0][lab] * B[1][lbc] * B[2][lac] * B[3][b] * B[4][a] * B[5][c] : 0) +
(b != c ? B[0][lac] * B[1][lab] * B[2][lbc] * B[3][a] * B[4][c] * B[5][b] : 0) +
(a != c ? B[0][lbc] * B[1][lac] * B[2][lab] * B[3][c] * B[4][b] * B[5][a] : 0) +
(a != b && b != c && a != c ?
B[0][lbc] * B[1][lab] * B[2][lac] * B[3][b] * B[4][c] * B[5][a] +
B[0][lac] * B[1][lbc] * B[2][lab] * B[3][c] * B[4][a] * B[5][b] : 0);
}
vi G[maxn],E[maxn];
int tim;
LL cst[maxn];
int main(){
read(n);
rep(t,0,5) rep(i,1,n) read(A[t][i]);
rep(t,0,2) rep(i,1,n) for(int k=i;k<=n;k+=i) B[t][i] += A[t][k];
mu[1] = 1;
rep(i,2,n){
if(!vis[i]) pr[cnt_pr++] = i , mu[i] = -1;
for(int j=0;pr[j] * i <= n;j++){
vis[i * pr[j]] = 1;
if(i % pr[j]) mu[i * pr[j]] = -mu[i];
else{
mu[i * pr[j]] = 0;
break;
}
}
}
memset(vis,0,sizeof vis);
rep(t,3,5) rep(i,1,n) for(int k=i,p=1;k<=n;k+=i,p++) B[t][k] += A[t][i] * mu[p];
rep(i,1,n) upd(i,i,i,i,i,i);
rep(i,1,n){
static int ar[maxn]={},cnt,t;
cnt = 0;
for(int j=i;j<=n;j+=i) ar[++cnt] = j;
rep(j,1,cnt) for(int k=1;k<j && (t = ar[j] / i * ar[k]) <= n;k++) if(gcd(ar[j] , ar[k]) == i){
int x = ar[j] , y = ar[k];
upd(x,x,y,x,t,t);
upd(y,y,x,y,t,t);
in[x] ++ , in[y] ++;
G[x].pb(mp(y,t));
}
}
rep(i,1,n) for(auto v:G[i])
if(in[i] < in[v.first]) E[i].pb(v);
else E[v.first].pb(mp(i,v.second));
rep(i,1,n){
++tim;
for(auto v:E[i]) vis[v.first] = tim , cst[v.first] = v.second;
for(auto v:E[i]) for(auto p:E[v.first])
if(vis[p.first] == tim)
upd(i,v.first,p.first,v.second,p.second,cst[p.first]);
}
printf("%llu",(unsigned long long)ans);
}