题目描述
有n个正整数,第i个为ai。
求有多少个正整数对(l,r)满足1≤l≤r≤n且
是完全平方数,即求有多少个区间满足区间内所有数的乘积是完全平方数。
输入
第一行一个正整数n。
第二行n个正整数,第i个为ai。
输出
输出一个非负整数,表示答案。
样例输入
4 2 2 3 3
样例输出
3
提示
对于100%的数据,n,ai≤100000。
分析
考虑质因数分解,若区间乘为完全平方数,则每个质数的数量应为偶数,可以用bitset来维护每一个质数的数量(1奇0偶),可以考虑枚举每一个区间的r(右端点),类似求异或和为0的区间,则答案可以为ans+=mp【1,r】,即加上与1到r的bitset相同的区间的数量,假设为【1,x】,那么【x+1,r】的bitset即为全0,符合条件。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mod 998244353
#define PII pair<int,int>
bitset<10000>q;
unordered_map<bitset<10000>,int>mp;
const int N=1e5+1;
int prime[10010],cnt;
int vis[N],id[N];
void oula()
{
for(int i=2;i<N;i++)
{
if(!vis[i]){id[i]=cnt;prime[cnt++]=i;}
for(int j=0;j<cnt;j++)
{
if(i*prime[j]>=N)break;
vis[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
int main ()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
oula();
mp[q]++;
int n;cin>>n;
ll ans=0;
for(int i=1;i<=n;i++)
{
int x;cin>>x;
for(int j=0;prime[j]*prime[j]<=x&&j<cnt;j++)
{
if(x%prime[j])continue;
int num=0;
while(x%prime[j]==0)
{
num++;
x/=prime[j];
}
if(num&1)q[j]=q[j]^1;
}
if(x>1)q[id[x]]=q[id[x]]^1;
ans+=mp[q];
mp[q]++;
}
cout<<ans;
return 0;
}