2018.10.31【校內模擬】一串數字(唯一分解)(貪心)

傳送門


解析:

其實很容易想到分解質因數,然後次數%3\%3後合併計算出它的特徵數,同時計算出不能與它共同選擇的數的特徵數。

顯然特徵數相同的數可以合併。然後兩個中貪心就是了。

注意所有本來就是立方數的數當中,我們直接選擇價值最大的那個。


代碼:

#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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章