CF1470B. Strange Definition
题意:
定义如果两个数
x
,
y
x,y
x,y满足
l
c
m
(
x
,
y
)
g
c
d
(
x
,
y
)
\cfrac{lcm(x,y)}{gcd(x,y)}
gcd(x,y)lcm(x,y)是一个完全平方数,则称
(
x
,
y
)
(x,y)
(x,y)相邻。
给一个数列
a
[
1...
n
]
a[1...n]
a[1...n],定义
d
i
d_i
di是和
a
i
a_i
ai相邻的元素的个数。定义数列的美丽程度为
max
1
≤
i
≤
n
d
i
\max\limits_{1\le i\le n} d_i
1≤i≤nmaxdi。
每一秒钟过后,每个
a
i
a_i
ai会变成
∏
a
i
和
a
j
相
邻
a
j
\prod\limits_{a_i和a_j相邻} a_j
ai和aj相邻∏aj,给你过去的时间,你要输出这么长时间过去后,数列的美丽程度。
思路:
由唯一分解定理可知,一个数可以表示成
x
=
p
1
a
1
p
2
a
2
⋯
p
n
a
n
x=p_1^{a_1}p_2^{a_2}\cdots p_n^{a_n}
x=p1a1p2a2⋯pnan。
g
c
d
(
x
,
y
)
=
p
1
min
(
a
x
,
1
,
a
y
,
1
)
p
2
min
(
a
x
,
2
,
a
y
,
2
)
⋯
p
n
min
(
a
x
,
n
,
a
y
,
n
)
gcd(x,y)=p_1^{\min(a_{x,1},a_{y,1})}p_2^{\min(a_{x,2},a_{y,2})}\cdots p_n^{\min(a_{x,n},a_{y,n})}
gcd(x,y)=p1min(ax,1,ay,1)p2min(ax,2,ay,2)⋯pnmin(ax,n,ay,n)
l
c
m
(
x
,
y
)
=
p
1
max
(
a
x
,
1
,
a
y
,
1
)
p
2
max
(
a
x
,
2
,
a
y
,
2
)
⋯
p
n
max
(
a
x
,
n
,
a
y
,
n
)
lcm(x,y)=p_1^{\max(a_{x,1},a_{y,1})}p_2^{\max(a_{x,2},a_{y,2})}\cdots p_n^{\max(a_{x,n},a_{y,n})}
lcm(x,y)=p1max(ax,1,ay,1)p2max(ax,2,ay,2)⋯pnmax(ax,n,ay,n)
可得
k
=
l
c
m
(
x
,
y
)
g
c
d
(
x
,
y
)
=
p
1
∣
a
x
,
1
−
a
y
,
1
∣
p
2
∣
a
x
,
2
−
a
y
,
2
∣
⋯
p
n
∣
a
x
,
n
−
a
y
,
n
∣
k=\cfrac{lcm(x,y)}{gcd(x,y)}=p_1^{|a_{x,1}-a_{y,1}|}p_2^{|a_{x,2}-a_{y,2}|}\cdots p_n^{|a_{x,n}-a_{y,n}|}
k=gcd(x,y)lcm(x,y)=p1∣ax,1−ay,1∣p2∣ax,2−ay,2∣⋯pn∣ax,n−ay,n∣
可见,如果
k
k
k是完全平方数,那么对于
i
∈
[
1
,
n
]
,
∣
a
x
i
−
a
y
,
i
∣
i\in[1,n],|a_{x_i}-a_{y,i}|
i∈[1,n],∣axi−ay,i∣都是偶数。也就是对于两个数满足
a
x
,
i
≡
a
y
,
i
(
m
o
d
2
)
a_{x,i}\equiv a_{y,i}(\mod 2)
ax,i≡ay,i(mod2)。
这样我们令
x
′
=
p
1
a
1
m
o
d
2
p
2
a
2
m
o
d
2
⋯
p
n
a
n
m
o
d
2
x^{'}=p_1^{a_1\mod 2}p_2^{a_2\mod 2}\cdots p_n^{a_n\mod 2}
x′=p1a1mod2p2a2mod2⋯pnanmod2,相同就表示他们相邻。
可以发现,时刻只有
0
0
0和其他的区别,如果
0
0
0时刻过后,有偶数个数是相邻的,那么相乘
x
′
=
1
x^{'}=1
x′=1。
先预处理
1000
1000
1000以内的素数,否则会T.
代码:
#include<bits/stdc++.h>
#define pii pair<int,int>
#define int long long
#define cl(x,y) memset(x,y,sizeof(x))
#define loop(x,y,z) for(x=y;x<=z;x++)
#define reve(x,y,z) for(x=y;x>=z;x--)
#define ct cerr<<"Time elapsed:"<<1.0*clock()/CLOCKS_PER_SEC<<"s.\n";
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define lson x<<1,l,mid
#define rson x<<1|1,mid+1,r
#define INF 1e18
const int N=1e3+10;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const double pi=acos(-1);
using namespace std;
int prim[N],ok[N],pos=0;
void init()
{
int n=N-1,i,j;
for(i=2;i<=n;i++)
{
if(ok[i]==0)
prim[++pos]=i;
for(j=1;j<=pos;j++)
{
if(i*prim[j]>n)
break;
ok[i*prim[j]]=1;
if(i%prim[j]==0)
break;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin>>t;
init();
while(t--)
{
int n,i,j,ans1=0;
cin>>n;
map<int,int> m;
for(i=1;i<=n;i++)
{
int x;
cin>>x;
int tot=1;
for(j=1;prim[j]<=x;j++)
{
if(j>pos)
break;
if(x%prim[j]==0)
{
int sum=0;
while(x%prim[j]==0)
{
x/=prim[j];
sum++;
}
if(sum%2==1)
tot*=prim[j];
}
}
if(x>1)
tot*=x;
m[tot]++;
ans1=max(m[tot],ans1);
}
int ans2=0;
for(auto it:m)
{
if(it.se%2==0 && it.fi!=1)
m[1]+=it.se;
it.se=0;
}
ans2=max(ans1,m[1]);
int q;
cin>>q;
while(q--)
{
int w;
cin>>w;
if(w==0)
cout<<ans1<<endl;
else
cout<<ans2<<endl;
}
}
return 0;
}