题解:P10827 [EC Final 2020] Square
前言
各位大佬写的题解稍稍有些有些简短,有些细节没有点到(看不到我),特来发篇题解(〃´-ω・)
此外,向管理员大大致歉,因对LaTeX使用不太熟练与未能对题解进行检查,一不小心添加了多余的积分符号(现已更正),造成还需管理员大大重新审核的严重后果,在此庄重宣布:
管理员大大,对不起!我错了!○| ̄|_
正文
分析
首先简单理解一下题意:
创造一个
设完全平方数为
对
可得
若
由此得出结论,完全平方数的质因子分解的每项指数都为偶数。
把
如果
对每个
但是有一个问题,
因为只要知道 好绕)。
设
- 如果质因数
i 的指数都为偶数,则cnt_{i} 为0 ,此时不用做任何操作。 - 如果质因数
i 的指数有为奇数的,则cnt_{i} 不为0 ,此时有两种选择:一、将所有质因数i 的指数为奇数的数都乘上质因数i ,让质因数i 的指数都为偶数;二、将所有质因数i 的指数为不为奇数的数都乘上质因数i ,让所有数都有质因数i 并将质因数i 的指数都为奇数。
嗯 (⊙o⊙)… 。非常抽象,我们设
对于第一种可能,简单直白,不做任何操作,
对于第二种可能,举个栗子
我们假设
对于质因数
对于质因数
为了将
我们再假设
对于质因数
对于质因数
为了将
为了最优,我们还可以给
有质因数2指数为奇数的数有
可以这么做的原因是
思路
开始的时候预处理好范围内所有数分解出来的质因子的指数,放进
之后,对于每个输入的
然后,我们再遍历所有的质因数,如果指数都为偶数或没有出现,也就是
最后,输出答案
代码
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N=1e6+10;
const int mod=1e9+7;
int n,ans=1;
int a[N],cnt[N];
map<int,int> mp[N];
bool isp[N];
int ksm(int a,int b,int c){
if(b==0) return 1%c;
if(b==1) return a%c;
int t=ksm(a,b/2,c);
if(b%2==0) return t*t%c;
return t*t%c*a%c;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
for(int i=2;i<=1e6;i++){
if(isp[i]){
continue;
}
for(int j=i;j<=1e6;j+=i){
isp[j]=1;
int x=j;
while(x%i==0){
mp[j][i]++;
x/=i;
}
}
isp[i]=0;
}
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
for(map<int,int>::iterator it=mp[a[i]].begin();it!=mp[a[i]].end();it++){
int x=it->first,y=it->second;
if(y%2!=0){
cnt[x]++;
}
}
}
for(int i=2;i<=1e6;i++){
if(isp[i]){
continue;
}
if(cnt[i]!=0&&cnt[i]<n){
ans=ans*ksm(i,min(cnt[i],n-cnt[i]),mod)%mod;
}
}
cout<<ans<<endl;
return 0;
}
时间复杂度