传送门
解析:
其实很容易想到分解质因数,然后次数后合并计算出它的特征数,同时计算出不能与它共同选择的数的特征数。
显然特征数相同的数可以合并。然后两个中贪心就是了。
注意所有本来就是立方数的数当中,我们直接选择价值最大的那个。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline int getint(){
re int num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
cs int N=100005;
cs int P=100005;
int prime[P],pcnt;
bool mark[P];
inline void linear_sieves(int len=P-5){
for(int re i=2;i<=len;++i){
if(!mark[i])prime[++pcnt]=i;
for(int re j=1;j<=pcnt&&i*prime[j]<=len;++j){
mark[i*prime[j]]=true;
if(!(i%prime[j]))break;
}
}
}
inline pair<ll,ll> factor(int x){
ll ori=1,rev=1;
for(int re i=1;i<=pcnt&&prime[i]<=x;++i){
int cnt=0;
while(x==x/prime[i]*prime[i])x/=prime[i],++cnt;
cnt%=3;
if(cnt)(cnt==2)?(ori*=1ll*prime[i]*prime[i],rev*=prime[i]):(rev*=1ll*prime[i]*prime[i],ori*=prime[i]);
}
return make_pair(ori,rev);
}
ll cost[N],revcost[N];
int n;
ll ans;
signed main(){
linear_sieves();
n=getint();
for(int re i=1;i<=n;++i){
int x=getint(),val=getint();
pair<ll,ll> sieve=factor(x);
if(sieve.first==1){
ans=max(ans,1ll*val);
continue;
}
else (sieve.first>sieve.second?revcost[sieve.second]:cost[sieve.first])+=val;
}
for(int re i=2;i<N;++i)ans+=max(cost[i],revcost[i]);
cout<<ans;
return 0;
}