不是,哥们

题目链接

戳我

\(Solution\)

很容易发现对于每个\(ai^2\)的因子最多在5000以内,所以先将\(ai\)质因数分解然后求出\(ai^2\)的因子然后看每个因子出现了多少次加起来即可

\(Code\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
    while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
    return f*x;
}
int a[100010],bj[1000010];
int vis[1000010],prime[1000010],tot;
void init(){
	int N=1e6;
	for(int i=2;i<=N;i++){
		if(!vis[i]) prime[++tot]=i;
		for(int j=1;j<=tot;j++){
			if(prime[j]*i>N) break;
			vis[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}	
}
vector<int> f[100010];
vector<int> b[100010];
vector<int> e[100010];
void dfs(int x,int sum,int id){
	if(x==f[id].size()) return ;
	int p=1;
	for(int i=0;i<=b[id][x];i++){
		if(p!=1) e[id].push_back(sum*p);
		dfs(x+1,sum*p,id);
		p=p*f[id][x];
	}
}
signed main() {
	init();
	int n=read(),ans=0;
	for(int i=1;i<=n;i++) {
		a[i]=read();
		int x=a[i];
		for(int j=1;j<=tot;j++){
			if(x%prime[j]==0){
				f[i].push_back(prime[j]);
				int ans=0;
				while(x%prime[j]==0) x/=prime[j],ans++;
				b[i].push_back(ans*2);
			}
			if(x==1) break;
		}
		e[i].push_back(1);
		dfs(0,1,i);		
	}
	bj[a[n]]++;
	for(int i=n-1;i>=1;i--){
		for(int j=0;j<e[i].size();j++){
			if(e[i][j]>1000000) continue;
			ans+=bj[e[i][j]]; 
		} 
		bj[a[i]]++;
	}
	cout<<ans;
}
posted @ 2024-05-12 21:34  撤云  阅读(83)  评论(0编辑  收藏  举报
……