CF2275F Tea Blend 题解
考虑如何区。
首先完全平方数在拆质因数分解的时候,每个质因子的个数都是偶数。
我们对于一个数
那么我们在判断
后者扫一遍做,前者可以预处理。具体你怎么维护这个
因为每个数不同的质因数数量非常少,所以这样做是不会 TLE 的。
代码写得很史,将就看吧 /kel。
::::success[code && submission]
#include<bits/stdc++.h>
#define LL long long
#define UInt unsigned int
#define ULL unsigned long long
#define LD long double
#define pii pair<int,int>
#define pLL pair<LL,LL>
#define pDD pair<LD,LD>
#define fr first
#define se second
#define pb push_back
#define isr insert
#define _i128 __int128
using namespace std;
const int N = 2e5+5;
const int K = 1e6+5;
const LL up = 1000000;
const LL Bas1 = 29;
const LL Bas2 = 233;
const LL MOD1 = 998244353;
const LL MOD2 = 1e9+7;
int T,n,a[N];
pLL val[N];
int cnt,p[K],mnp[K],id[K];
LL q1[K],q2[K];
pLL sta;
LL t[K],Ans;
bool vis[K];
map<pLL,int> mp;
LL read(){
LL su=0,pp=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')pp=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){su=su*10+ch-'0';ch=getchar();}
return su*pp;
}
void init(){
vis[0]=1,vis[1]=1;
cnt=0;
for(LL i=2;i<=up;i++){
if(!vis[i])
p[++cnt]=i,id[i]=cnt,mnp[i]=i;
for(int j=1;j<=cnt&&p[j]*i<=up;j++){
vis[p[j]*i]=1;
mnp[p[j]*i]=p[j];
if(i%p[j]==0)continue;
}
}
return;
}
void init_2(){
q1[0]=1,q2[0]=1;
for(int i=1;i<=cnt;i++)
q1[i]=q1[i-1]*Bas1%MOD1,
q2[i]=q2[i-1]*Bas2%MOD2;
return;
}
pLL sol(LL num){
LL now1=0,now2=0;
while(num>1){
LL x=id[mnp[num]],c=0;
while(num%p[x]==0)num/=p[x],c^=1;
now1=(now1+c*q1[x])%MOD1;
now2=(now2+c*q2[x])%MOD2;
}
return {now1,now2};
}
void add(LL num){
while(num>1){
LL x=id[mnp[num]],c=t[x];
sta.fr=(sta.fr-c*q1[x]%MOD1+MOD1)%MOD1;
sta.se=(sta.se-c*q2[x]%MOD2+MOD2)%MOD2;
while(num%p[x]==0)num/=p[x],t[x]^=1;
c=t[x];
sta.fr=(sta.fr+c*q1[x]%MOD1)%MOD1;
sta.se=(sta.se+c*q2[x]%MOD2)%MOD2;
}
return;
}
void del(LL num){
while(num>1){
LL x=mnp[num],c=0;
while(num%x==0)num/=x;
t[id[x]]=0;
}
return;
}
int main(){
T=read();init();init_2();
while(T--){
n=read();
for(int i=1;i<=n;i++)a[i]=read();
mp.clear();
for(int i=1;i<=n;i++)
val[i]=sol(a[i]),mp[val[i]]++;
Ans=0,sta={0,0};
for(int i=1;i<=n;i++)
add(a[i]),Ans+=mp[sta];
for(int i=1;i<=n;i++)del(a[i]);
cout<<Ans<<"\n";
}
return 0;
}
::::
如果本篇题解对你有帮助的话,麻烦你点一个小小的赞,真是太感谢啦!