B 可爱捏

B 可爱捏

考虑完全立方数的构成一定是幂 \(\bmod 3\) 互补的两个数,如 \(2^2*3^3,2^4*3^6\),那么暴力的想法就是暴力分解,然后用 map 记录互补的数,但是这样因数分解复杂度太高了。

考虑优化,我们考虑分解出 \(\le \sqrt[3]a_i\) 的数,然后如果超过了,无非三种情况:

  1. 一个质数或两个不等的质数,此时补数需要乘上平方。
  2. 两个一样的质数,此时补数需要乘上一个,就是开根号。

复杂度就被优化成了 \(O(n\sqrt[3]a_i)\)

但是不知道为什么只有80.

#include<iostream>
#include<unordered_map>
#include<cmath>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while

typedef long long ll;
const int N=100010;
const ll INF=1e10;
int n,ans;
bool lf=1;
ll a[N];
unordered_map<ll,ll>mp;
unordered_map<ll,int>cnt;
#define ch(x) (x>=INF)
int main(){
	#ifdef ONLINE_JUDGE
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	#endif
	cin>>n;
	E(i, n)cin>>a[i];
	E(i, n){
		ll x=a[i],xx=1;
		__int128 yy=1;
		ll cb=cbrt(x);
		// printf("x=%d,cbrt=%d\n",x,cb);
		if(cb*cb*cb==x){
			// cout<<"HAve\n";
			ans+=lf,lf=0;
			continue;
		}
		bool flag=0;
		for(ll j=2;j*j*j<=a[i];++j)
			if(x%j==0){
				int cnt=1;
				x/=j;
				Wh(x%j==0)cnt=cnt==2?0:cnt+1,x/=j;
				L(i, cnt)xx*=j;
				if(!cnt)continue;
				L(i, 3-cnt){
					yy*=j;
					if(yy>INF){
						flag=1;
						break;
					}
				}
				// cout<<cnt<<'\n';
			}
		if(flag){
			++ans;
			continue;
		}
		xx*=x;
		ll q=sqrt(x);
		if(q*q==x){
			if(ch(yy*q)){
				++ans;
				continue;
			}
			yy*=q;
		}
		else{
			if(ch(yy*x*x)){++ans;continue;}
			yy*=x*x;
		}
		++cnt[xx];
		ll yyy=yy;
		if(xx>yyy)swap(xx,yyy);
		// cout<<xx<<' '<<yyy<<'\n';
		mp[xx]=yyy;
	}
	for(auto v:mp){
		ans+=max(cnt[v.first],cnt[v.second]);
	}
	cout<<ans;
	return 0;
}
posted @ 2023-11-17 12:56  wscqwq  阅读(1)  评论(0编辑  收藏  举报