题意是多少对 互不相同的下标i,j,k满足对应数等比
很自然的想到了枚举最大数,然后找到因子就做完了
1e9以内因子最多1e3,这个不难发现,知道怎么通过质因数分解得到因子个数就知道怎么算了。
毫无优化,全是暴力。居然过了
可以通过手写哈希去掉map的log,而且不难
我用了一个写的时候想到的哈希写法试了试,不过似乎常数很大?并没有优化多少
map写法
#include<bits/stdc++.h>
using namespace std;
const int P=998244353,N=4e4+10,inf=1e9+10;
using ll=long long;
bool st[N];
int pri[N],cnt;
void init()
{
for(int i=2;i<N;++i)
{
if(!st[i])pri[++cnt]=i;
for(int j=1;pri[j]*i<N;++j)
{
st[pri[j]*i]=1;
if(i%pri[j]==0)break;
}
}
}
vector<array<int,2>>vec;
void func(int n)
{
vec.clear();
for(int i=1;i<=cnt;++i)
{
if(n==1)return ;
if(n%pri[i]==0)
{
vec.push_back({pri[i],0});
while(n%pri[i]==0)++vec.back()[1],n/=pri[i];
}
}
if(n>1)vec.push_back({n,1});
}
vector<int>e;
void dfs(int now,int x)
{
if(now==vec.size()){e.push_back(x);return ;}
dfs(now+1,x);
for(int i=1;i<=vec[now][1];++i)
{
x=x*vec[now][0];
dfs(now+1,x);
}
}
ll C(int n)
{
if(n<3)return 0;
return 1ll*n*(n-1)*(n-2);
}
void solve()
{
int n;scanf("%d",&n);
vector<int>a(n);for(auto &v:a)scanf("%d",&v);
map<int,int>mp;
for(auto &v:a)mp[v]++;
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end());
ll rs=0;
for(auto &v:a)
{
func(v);e.clear();dfs(0,1);
//for(auto t:e)cout<<t<<" \n"[t==e.back()];
for(auto &t:e)
{
if(t==1)rs+=C(mp[v]);
else
{
int x=v/t;if(x%t)continue;
int y=x/t;
rs+=1ll*mp[x]*mp[y]*mp[v];
}
}
}
printf("%lld\n",rs);
}
int main()
{
init();
int T=1;scanf("%d",&T);
while(T--)solve();
}
取模哈希试了下
只从2500ms卡到了1900ms
#include<bits/stdc++.h>
using namespace std;
const int P=33331,N=33333+10,inf=1e9+10;
using ll=long long;
bool st[N];
int pri[N],cnt;
vector<array<int,2>>hsh[P+2];
void init()
{
for(int i=2;i<N;++i)
{
if(!st[i])pri[++cnt]=i;
for(int j=1;pri[j]*i<N;++j)
{
st[pri[j]*i]=1;
if(i%pri[j]==0)break;
}
}
}
vector<array<int,2>>vec;
void func(int n)
{
vec.clear();
for(int i=1;i<=cnt;++i)
{
if(n==1)return ;
if(n%pri[i]==0)
{
vec.push_back({pri[i],0});
while(n%pri[i]==0)++vec.back()[1],n/=pri[i];
}
}
if(n>1)vec.push_back({n,1});
}
vector<int>e;
void dfs(int now,int x)
{
if(now==vec.size()){e.push_back(x);return ;}
dfs(now+1,x);
for(int i=1;i<=vec[now][1];++i)
{
x=x*vec[now][0];
dfs(now+1,x);
}
}
ll C(int n)
{
if(n<3)return 0;
return 1ll*n*(n-1)*(n-2);
}
int find(int x)
{
array<int,2>z={x,0};
auto t=lower_bound(hsh[x%P].begin(),hsh[x%P].end(),z)-hsh[x%P].begin();
if(t==hsh[x%P].size())return 0;
if(hsh[x%P][t][0]==x)return hsh[x%P][t][1];
return 0;
}
void solve()
{
int n;scanf("%d",&n);
vector<int>a(n);for(auto &v:a)scanf("%d",&v);
map<int,int>mp;
for(auto &v:a)mp[v]++;
sort(a.begin(),a.end());
a.erase(unique(a.begin(),a.end()),a.end());
ll rs=0;
for(auto v:a)hsh[v%P].push_back({v,mp[v]});
set<int>S;for(auto v:a)
{
if(S.find(v%P)!=S.end())continue;
S.insert(v%P);sort(hsh[v%P].begin(),hsh[v%P].end());
}
for(auto &v:a)
{
func(v);e.clear();dfs(0,1);
//for(auto t:e)cout<<t<<" \n"[t==e.back()];
for(auto &t:e)
{
if(t==1)rs+=C(find(v));
else
{
int x=v/t;if(x%t)continue;
int y=x/t;
rs+=1ll*find(x)*find(y)*find(v);
}
}
}
printf("%lld\n",rs);
for(auto v:a)hsh[v%P].clear();
}
int main()
{
init();
//cout<<pri[cnt]<<endl;
int T=1;scanf("%d",&T);
while(T--)solve();
}