power products
程序员文章站
2022-06-12 19:28:47
...
解题思路:
tle思路:计算出每个值出现的次数,然后枚举x ,因为我看乘机最大也才1e10嘛 ,但是不行,当k=2的时候会卡,别的情况应该不会。哎,,
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
const int N=100010;
ll a[N];
const int mod = 998244353;
map<ll,int>mp;
ll qmi(ll a,int b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a;
a = a*a;
b>>=1;
}
return res;
}
int main()
{
int n,k;
cin>>n>>k;
ll maxv=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
mp[a[i]]++;
maxv=max(maxv,a[i]);
}
ll res=0;
ll ans2=0;
for(int i=1;;i++)
{
ll tt=qmi(i,k);
if(tt>maxv*maxv) break;
for(auto it:mp)
{
ll z = it.first;
ll y = it.second;
if(tt%z==0)
{
ll zz = tt/z;
if(zz!=z)
res+=y*mp[zz];
else
ans2+=mp[zz]*(mp[zz]-1)/2;
}
}
}
cout<<res/2 + ans2 <<endl;
return 0;
}
正确思路:我看了一个用哈希解决的方法,将所有数质因数分解,如果乘积是x的k次,那么他们每个质因数的幂一定是k的整数倍,我们将每个质因数的次数哈希,然后开一个bhash用来计算和它相补的值,最后用个map来查询bash哈希值对应的次数,最后加起来就是答案。
/*#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
const int N=100010;
ll a[N];
const int mod = 998244353;
map<ll,int>mp;
ll qmi(ll a,int b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a;
a = a*a;
b>>=1;
}
return res;
}
vector<ll>Q;
int main()
{
int n,k;
cin>>n>>k;
ll maxv=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
mp[a[i]]++;
maxv=max(maxv,a[i]);
}
ll res=0;
ll ans2=0;
for(int i=1;;i++)
{
ll tt = qmi(i,k);
if(tt>maxv * maxv) break;
Q.push_back(tt);
}
for(int i=0;i<Q.size();i++)
{
ll tt=Q[i];
if(tt>maxv*maxv) break;
for(auto it:mp)
{
ll z = it.first;
ll y = it.second;
if(z*z>tt) break;
if(tt%z==0)
{
ll zz = tt/z;
if(zz!=z)
res+=y*mp[zz];
else
ans2+=mp[zz]*(mp[zz]-1)/2;
}
}
}
cout<<res + ans2 <<endl;
return 0;
}*/
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
const int N=100010;
ll a[N];
const int mod = 998244353;
typedef unsigned long long ull;
ull base = 131;
ull Hash[N];
int prime[N];
int cnt;
bool st[N];
int n,k;
int primeid[N];
void init()
{
for(int i=2;i<N;i++)
{
if(!st[i])
{
primeid[i]=cnt;
prime[cnt++]=i;
}
for(int j=0;i*prime[j]<=N-1;j++)
{
if(i%prime[j]==0) break;
st[i*prime[j]]=true;
}
}
}
map<ull,int>mp;
ll qmi(ll a,int b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a;
a = a*a;
b>>=1;
}
return res;
}
int work(int u)
{
ll p = a[u];
ull xhash=0;
ull bhash=0;
for(int i=0;i<cnt;i++)
{
if(prime[i]*prime[i]>p) break;
if(p%prime[i]==0)
{
int pcnt=0;
while(p%prime[i]==0)
{
p/=prime[i];
pcnt++;
if(pcnt>=k)
pcnt-=k;
}
xhash+=pcnt*Hash[i+1];
bhash+=((k-pcnt)%k+k)%k*Hash[i+1];
}
}
if(p!=1)
{
xhash+=1*Hash[primeid[p]+1];
bhash+=(k-1)*Hash[primeid[p]+1];
}
ll res=mp[bhash];
mp[xhash]++;
return res;
}
int main()
{
cin >> n >> k;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
Hash[0]=1;
init();
//cout<<cnt<<endl;
for(int i=1;i<cnt;i++)
Hash[i]=Hash[i-1]*base;;
ll res=0;
for(int i=n;i>=1;i--)
res+=work(i);
cout<<res<<endl;
return 0;
}
推荐阅读
-
android 添加按(power键)电源键结束通话(挂断电话)
-
国外著名论坛程序IPB(Invision Power Board)在nginx下的配置示例
-
android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
-
Mac应用程序的Power Nap功能如何关闭
-
A7VMX主板NB和SB POWER GOOD线路图
-
【TOJ 2406】Power Strings(kmp找最多重复子串)
-
台电Tbook 16 Power怎么样?台电Tbook 16 Power测评
-
主板NO POWER检修流程
-
电脑开机蓝屏显示please power down等英文该怎么办?
-
POJ3233Matrix Power Series(矩阵快速幂)