hust 2015夏休み合宿
7841 ワード
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82839#problem/C
14年鞍山地区の試合のテーマは…
その時は満場で4番目の問題だったと記憶していますが…
話をする時、麗潔姉さんは「莫比烏斯反演blablabla」と言いました.
全然分かりませんでした.
えっと、初めてモビル反転というものに触れました.これは数論で重要なようです.
この問題で注意したいのは、xとの互質の個数を求める時、1とどの正の整数も互いに質的なものですが、1と1の互質はこの組は条件に合わないです.判断してください.
Mobius関数を求めて、ふるいがあるようです.(賈志鵬の線形ふるい.pdfを見てください.)そして赤い本には1~nのmobius関数の値を求める方法があります.
そして強制的に変換されたタイプが2発のWAをピットしました.long longを開くには、強制変換を書かないとWAになります.なぜかまだ分かりません.他の人が書いているコードを見たらあります.加えて、結果は過ぎました.
分かりました.zj先輩、ありがとうございます.
等号の右側がintなら、左がLLです.超intもアウトします.
つまりc=a*bです aとbがintなら Cはlong longです a*bがIntを超えたら、オフラインに…
まず二つのintタイプをlong long longに変換します. c=long long(a)*long long(b)と書く.
14年鞍山地区の試合のテーマは…
その時は満場で4番目の問題だったと記憶していますが…
話をする時、麗潔姉さんは「莫比烏斯反演blablabla」と言いました.
全然分かりませんでした.
えっと、初めてモビル反転というものに触れました.これは数論で重要なようです.
この問題で注意したいのは、xとの互質の個数を求める時、1とどの正の整数も互いに質的なものですが、1と1の互質はこの組は条件に合わないです.判断してください.
Mobius関数を求めて、ふるいがあるようです.(賈志鵬の線形ふるい.pdfを見てください.)そして赤い本には1~nのmobius関数の値を求める方法があります.
そして強制的に変換されたタイプが2発のWAをピットしました.long longを開くには、強制変換を書かないとWAになります.なぜかまだ分かりません.他の人が書いているコードを見たらあります.加えて、結果は過ぎました.
分かりました.zj先輩、ありがとうございます.
等号の右側がintなら、左がLLです.超intもアウトします.
つまりc=a*bです aとbがintなら Cはlong longです a*bがIntを超えたら、オフラインに…
まず二つのintタイプをlong long longに変換します. c=long long(a)*long long(b)と書く.
/*******************************************************************
Author :111qqz
*******************************************************************/
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <map>
#include <stack>
#include <queue>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int inf = 0x7fffffff;
const int N=1E5+3;
int T,n;
int mu[N],a[N];
LL mul[N],p[N],sumt[N];
void getmu()
{
for (int i = 1 ; i <N ; i++)
{
int target = i ==1?1:0;
int delta = target - mu[i];
mu[i] = delta;
for ( int j = i+i; j <N ; j=j+i)
mu[j] = mu[j] + delta;
}
}
int main()
{
cin>>T;
getmu();
while (T--)
{
cin>>n;
// cout<<mu[n]<<endl;
memset(p,0,sizeof(p));
memset(sumt,0,sizeof(sumt));
memset(mul,0,sizeof(mul));
memset(a,0,sizeof(a));
for ( int i = 0 ; i < n ; i++ )
{
scanf("%d",&a[i]);
sumt[a[i]]++;
}
for ( int i = 1 ; i < N ; i++)
for ( int j = i ; j < N ; j=j+i)
{
mul[i] = mul[i] + sumt[j];
}
for ( int i = 1 ; i < N ; i++ )
for ( int j = i ; j < N ; j=j+i)
{
p[j] = p[j] + mul[i]*mu[i];
}
// p[1]--;// 1 1 ... id
// cout<<"p[1]:"<<p[1]<<endl;
// for ( int i = 0 ; i < n ; i++)
// cout<<"p[i]:"<<a[i]<<" "<<p[a[i]]<<endl;
LL ans=(LL)n*(n-1)*(n-2)/6;
LL sum=0;
for (int i=0;i<n;i++)
{
if (a[i]==1) continue;
sum+=(LL)p[a[i]]*(LL)(n-1-p[a[i]]);
}
sum =(LL)sum/2;
ans =(LL)(ans-sum);
cout<<ans<<endl;
}
return 0;
}