D. Strange Definition
由 l c m ( x , y ) = x y g c d ( x , y ) lcm(x,y)=\frac{xy}{gcd(x,y)} lcm(x,y)=gcd(x,y)xy可知,如果 l c m ( x , y ) g c d ( x , y ) = x y g c d 2 ( x , y ) \frac{lcm(x,y)}{gcd(x,y)}=\frac{xy}{gcd^2(x,y)} gcd(x,y)lcm(x,y)=gcd2(x,y)xy是完全平方数,那么 x y xy xy是完全平方数。
x y xy xy是完全平方数意味着将其质因数分解后,质因数的次数都是偶数次。不难知道将 x , y x,y x,y分别分解质因数后,各自质因数次幂奇偶性相同,也就是如果两个数分解质因数后,质数次幂奇偶性相同,则他们满足题目中的“相邻”条件。
对于0时刻,只需要统计奇偶性相同数的个数即可。
注意:如何记录?借用hash的思想记录,详细看代码
对于1时刻,如果上述其中一个组内元素个数是奇数,那么将他们相乘后得到的数分解质因数仍然是奇数次幂(1除外即此组不代表元素1)
如果组内元素个数是偶数,那么下一时刻相乘后得到的数分解质因数全部都是偶数次幂,它与可以其他组内元素个数是偶数的组或者某组代表的数是1合并。
不难知道其他时刻与1时刻状态相同。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ull P=19260817;
map<ull,int> mp;
void divide(int x)
{
ull hash=1;
for(int i=2;i<=x/i;i++)
if(x%i==0)
{
int cnt=0;
while(x%i==0) x/=i,cnt++;
if(cnt&1) hash=hash*i;
}
if(x>1) hash=hash*x;
mp[hash]++;
}
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
mp.clear();
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int a;
scanf("%d",&a);
divide(a);
}
int res1=0,res2=0;
for(auto &t:mp)
{
res1=max(res1,t.second);
if(t.second%2==0||t.first==1) res2+=t.second;
}
res2=max(res2,res1);
int q;
scanf("%d",&q);
while(q--)
{
ll op;
scanf("%lld",&op);
if(op==0) printf("%d\n",res1);
else printf("%d\n",res2);
}
}
return 0;
}
cf好像会卡掉hash,最开始我按照上述博客的方式记录,用base=131或13331都被卡错了,不过博客里面的base=19260817
竟然没被卡,神奇!
总结:如果不知道如何记录状态就考虑hash。
菜就多练,要不然训练总挂机
要加油哦~