大意:



%E7%9A%84%E5%80%8D%E6%95%B0&preview=true)
%7Cx%2C%E7%9F%B3%E5%AD%90x%E4%BC%9A%E8%A2%AB%E7%AC%ACi%E4%B8%AA%E9%9D%92%E8%9B%99%E8%B8%A9%E5%88%B0&preview=true)
%7Cx%E8%A1%A8%E7%A4%BA%E5%90%8E%E8%80%85%E6%98%AF%E5%89%8D%E8%80%85%E7%9A%84%E5%80%8D%E6%95%B0&preview=true)
%3D%5Cfrac%7B%5Cphi%20(q)*q%7D%7B2%7D&preview=true)
%E6%98%AF1%5Csim%20q-1%E4%B8%8Eq%E4%BA%92%E8%B4%A8%E7%9A%84%E6%95%B0%E7%9A%84%E5%92%8C%EF%BC%8C%5Cphi%20(q)%E6%98%AF1%5Csim%20q-1%E4%B8%8Eq%E4%BA%92%E8%B4%A8%E7%9A%84%E6%95%B0%E7%9A%84%E4%B8%AA%E6%95%B0&preview=true)
%3D%3D1%EF%BC%8C%E8%BF%99%E6%97%B6%E7%AD%94%E6%A1%88%E5%B0%B1%E6%98%AF%5Cfrac%7Bm*(m-1)%7D%7B2%7D&preview=true)
欧拉函数求和+思维




&preview=true)
*%5Cfrac%7B20%7D%7B2%7D%7D%7B2%7D&preview=true)

&preview=true)
*%5Cfrac%7B20%7D%7B4%7D%7D%7B2%7D&preview=true)

*m%7D%7B2%7D&preview=true)

&preview=true)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e4+10;
ll com[maxn];
ll t,n,m,ans;
ll euler(ll x) {
ll ans = x;
for (ll i = 2; i * i <= x; ++i) {
if (x % i == 0) {
ans = ans / i * (i - 1);
while (x % i == 0) x /= i;
}
}
if (x != 1) ans = ans / x * (x - 1);
return ans;
}
bool check(ll x) {
for(int i = 0; i < n; i++)
if(x%com[i] == 0)
return true;
return false;
}
int main() {
cin>>t;
for(ll cas=1;cas<=t;++cas,ans=0) {
bool Prime = false;
cin>>n>>m;
for(ll i=0,x,g;i<n;++i) {
cin>>x;
com[i]=__gcd(x,m);
if(com[i] == 1) Prime = true;
}
if(Prime) ans = m*(m-1)/2;
else {
for(int i = 2; i*i <= m; i++) if(m%i == 0){
if(check(i)) ans += euler(m/i)*m/2;
if(i*i!=m && check(m/i)) ans+= euler(i)*m/2;
}
}
printf("Case #%lld: %lld\n",cas,ans);
}
}
容斥原理




&preview=true)


%5E%7B2%7D)&preview=true)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<ll>v;
const int maxn=1e5+5;
ll cnt[maxn],sum[maxn];
int main(void) {
ll t,n,m;
cin>>t;
for(int cas=1;cas<=t;++cas) {
cin>>n>>m;
memset(cnt,0,sizeof cnt);
memset(sum,0,sizeof sum);
v.clear();
for(int i=2;i*i<m;++i) if(m%i==0) {
v.push_back(i);
v.push_back(m/i);
}
v.push_back(1);
sort(v.begin(),v.end());
for(ll i=1,x,g;i<=n;++i) {
cin>>x;
g=__gcd(x,m);
for(int j=0;j<v.size();++j) if(v[j]%g==0)
cnt[j]=1;
}
ll res=0;
for(int i=0;i<v.size();++i) {
res+=m*(m/v[i]-1)/2*(cnt[i]-sum[i]);
for(int j=i+1;j<v.size();++j) {
if(v[j]%v[i]==0) sum[j]+=cnt[i]-sum[i];
}
}
printf("Case #%lld: %lld\n",cas,res);
}
}