链接
先来看看求的是什么东西
令 c i c_i ci表示数字 i i i在给定区间中出现了几次, n = 1 0 7 n=10^7 n=107
∑ i = l r ∑ j = l r φ ( g c d ( a i , a j ) ) l c m ( a i , a j ) \sum_{i=l}^r \sum_{j=l}^r \varphi(gcd(a_i,a_j)) lcm(a_i,a_j) i=l∑rj=l∑rφ(gcd(ai,aj))lcm(ai,aj)
= ∑ i = 1 n ∑ j = 1 n φ ( g c d ( i , j ) ) l c m ( i , j ) c i c j = \sum_{i=1}^n \sum_{j=1}^n \varphi(gcd(i,j)) lcm(i,j) c_i c_j =i=1∑nj=1∑nφ(gcd(i,j))lcm(i,j)cicj
= ∑ d = 1 n d ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ n d ⌋ φ ( d ) i j c i d c j d [ ( i , j ) = 1 ] = \sum_{d=1}^n d \sum_{i=1}^{\lfloor\frac{n}{d}\rfloor} \sum_{j=1}^{\lfloor\frac{n}{d}\rfloor} \varphi(d) ij c_{id} c_{jd} [(i,j)=1] =d=1∑ndi=1∑⌊dn⌋j=1∑⌊dn⌋φ(d)ijcidcjd[(i,j)=1]
= ∑ d = 1 n d ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ n d ⌋ φ ( d ) i j c i d c j d ∑ t ∣ i ∧ t ∣ j μ ( t ) = \sum_{d=1}^n d \sum_{i=1}^{\lfloor\frac{n}{d}\rfloor} \sum_{j=1}^{\lfloor\frac{n}{d}\rfloor} \varphi(d) ij c_{id} c_{jd} \sum_{ t|i \wedge t|j } \mu(t) =d=1∑ndi=1∑⌊dn⌋j=1∑⌊dn⌋φ(d)ijcidcjdt∣i∧t∣j∑μ(t)
= ∑ d = 1 n d φ ( d ) ∑ t = 1 ⌊ n d ⌋ t 2 μ ( t ) ∑ i = 1 ⌊ n d t ⌋ ∑ j = 1 ⌊ n d t ⌋ i j c i d t c j d t = \sum_{d=1}^n d\varphi(d) \sum_{t=1}^{\lfloor\frac{n}{d}\rfloor} t^2 \mu(t) \sum_{i=1}^{\lfloor\frac{n}{dt}\rfloor} \sum_{j=1}^{\lfloor\frac{n}{dt}\rfloor} ij c_{idt} c_{jdt} =d=1∑ndφ(d)t=1∑⌊dn⌋t2μ(t)i=1∑⌊dtn⌋j=1∑⌊dtn⌋ijcidtcjdt
= ∑ d = 1 n d φ ( d ) ∑ t = 1 ⌊ n d ⌋ t 2 μ ( t ) ( ∑ i = 1 ⌊ n d t ⌋ i c i d t ) 2 = \sum_{d=1}^n d\varphi(d) \sum_{t=1}^{\lfloor\frac{n}{d}\rfloor} t^2 \mu(t) ( \sum_{i=1}^{\lfloor\frac{n}{dt}\rfloor} i c_{idt} )^2 =d=1∑ndφ(d)t=1∑⌊dn⌋t2μ(t)(i=1∑⌊dtn⌋icidt)2
换元,令 T = d t T=dt T=dt
= ∑ T = 1 n ∑ d ∣ T d φ ( d ) T 2 d 2 μ ( T d ) ( ∑ i = 1 ⌊ n T ⌋ i c i T ) 2 = \sum_{T=1}^n \sum_{d|T} d\varphi(d) \frac{T^2}{d^2} \mu(\frac{T}{d}) ( \sum_{i=1}^{\lfloor\frac{n}{T}\rfloor} i c_{iT} )^2 =T=1∑nd∣T∑dφ(d)d2T2μ(dT)(i=1∑⌊Tn⌋iciT)2
注意看 g ( T ) = ∑ d ∣ T d φ ( d ) T 2 d 2 μ ( T d ) g(T) = \sum_{d|T} d\varphi(d) \frac{T^2}{d^2} \mu(\frac{T}{d}) g(T)=∑d∣Tdφ(d)d2T2μ(dT)
这玩意是个积性函数,对 T = p k T=p^k T=pk分析发现, g ( T ) = T μ ( T ) g(T) = T\mu(T) g(T)=Tμ(T)
上式接着化简
a n s = ∑ T = 1 n T μ ( T ) ( ∑ i = 1 ⌊ n T ⌋ i c i T ) 2 ans = \sum_{T=1}^n T\mu(T) ( \sum_{i=1}^{\lfloor\frac{n}{T}\rfloor} i c_{iT} )^2 ans=T=1∑nTμ(T)(i=1∑⌊Tn⌋iciT)2
莫队搞一搞
别以为到这里就结束了
卡常简直把我给搞自闭了
必须写的优美否则就会 T L E TLE TLE成狗
我的自闭过程:
代码
#include <bits/stdc++.h>
#define maxn 100010
#define maxN 10000010
#define rep(_,__) for(_=1;_<=(__);_++)
#define sqr(x) ((x)*(x))
using namespace std;
typedef unsigned int uint;
typedef pair<uint,uint> pr;
uint prime[maxN/10], mu[maxN];
bool mark[maxN];
void shai(uint N)
{
uint i, j;
for(i=2;i<=N;i++)mark[i]=false;
*prime=0;
mu[1]=1;
for(i=2;i<=N;i++)
{
if(!mark[i])prime[++*prime]=i, mu[i]=-1;
for(j=1;j<=*prime and i*prime[j]<=N;j++)
{
mark[i*prime[j]]=true;
if(i%prime[j]==0)break;
mu[i*prime[j]]=-mu[i];
}
}
}
uint l[maxn], r[maxn], id[maxn], s[maxN], now, a[maxn], ans[maxn], S;
vector<pr> d[maxn];
void init()
{
uint i, j;
shai(10000000);
}
bool cmp(uint x, uint y)
{
if(l[x]/S==l[y]/S)return r[x]<r[y];
return l[x]/S < l[y]/S;
}
void upd(uint x, bool pos, vector<pr> &d)
{
for(auto T:d)
{
uint dlt = pos ? x/T.first : -(x/T.first);
now += T.second*dlt*((s[T.first]<<1)+dlt);
s[T.first] += dlt;
}
}
uint read(uint x=0)
{
uint c;
for(c=getchar();!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())x=x*10+c-0x30;
return x;
}
int main()
{
uint T, n, q, i, L, R, j;
init();
T=read();
while(T--)
{
n=read(), q=read();
S = sqrt(n);
rep(i,n)
{
a[i]=read();
d[i].clear();
for(j=1;j*j<=a[i];j++)
if(a[i]%j==0)
{
if(mu[j])
d[i].emplace_back(pr(j,j*mu[j]));
if(j!=a[i]/j and mu[a[i]/j])
d[i].emplace_back(pr(a[i]/j,a[i]/j*mu[a[i]/j]));
s[j]=s[a[i]/j]=0;
}
}
rep(i,q)
{
l[i]=read(), r[i]=read();
id[i]=i;
}
sort(id+1,id+q+1,cmp);
now = 0;
L=1, R=0;
rep(i,q)
{
for(;L<l[id[i]];L++)upd(a[L],false,d[L]);
for(;L>l[id[i]];L--)upd(a[L-1],true,d[L-1]);
for(;R>r[id[i]];R--)upd(a[R],false,d[R]);
for(;R<r[id[i]];R++)upd(a[R+1],true,d[R+1]);
ans[id[i]]=now;
}
rep(i,q)
{
printf("%u\n",ans[i]);
}
}
return 0;
}