【Codeforces】 CF1285F Classical?

题目链接

CF方向
Luogu方向

题目解法

考虑枚举最大公因数 d d d
从大到小枚举是 d d d 的倍数 x x x,考虑如果有 ( x , z ) = d (x,z)=d (x,z)=d,那么 x < y < z x<y<z x<y<z 的所有 y y y 都是无意义的
考虑把之前枚举的数的倍数 d d d 放入栈中维护,栈顶小,栈底大,如果栈中仍有与 x x x 互质的数,那么就弹出栈头
考虑计算栈中与 x x x 互质的数的个数,这个用莫反可以轻松求到,为 ∑ d ∣ i μ ( d ) ∗ s u m d \sum_{d|i}\mu(d)*sum_d diμ(d)sumd
其中 s u m d sum_d sumd 为栈中为 d d d 的个数的数
这样可以用 O ( n l o g 2 n ) O(nlog^2n) O(nlog2n) 求解

考虑对于 x , y x,y x,y l c m ( x , y ) = l c m ( x , z )    , z = y ( x , y ) lcm(x,y)=lcm(x,z)\;,z=\frac{y}{(x,y)} lcm(x,y)=lcm(x,z),z=(x,y)y,这里 x , z x,z x,z 是互质的,例如 [ 4 , 6 ] = [ 4 , 3 ] [4,6]=[4,3] [4,6]=[4,3],于是可以把 n n n 的约数都放入集合中,只需要对于 d = 1 d=1 d=1 的情况做一遍上述操作即可,时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N(100100),MX(100000);
int n,ans,a[N],cnt[N],sum[N],mu[N]; 
vector<int> g[N];
int stk[N],top;
inline int read(){
	int FF=0,RR=1;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
	for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
	return FF*RR;
}
int count(int x){//计算与x互质的数的个数 
	int res=0;
	for(int i=0;i<g[x].size();i++) res+=mu[g[x][i]]*sum[g[x][i]];
	return res;
}
void add(int x,int val){
	for(int i=0;i<g[x].size();i++) sum[g[x][i]]+=val;
}
signed main(){
	n=read();
	for(int i=1;i<=MX;i++) mu[i]=1;
	for(int d=1;d<=MX;d++){
		for(int i=d;i<=MX;i+=d) g[i].push_back(d);
		if(d==1) mu[d]=1;
		else if((d/g[d][1])%g[d][1]==0) mu[d]=0;
		else mu[d]=-mu[d/g[d][1]];
	}
	for(int i=1;i<=n;i++){
		a[i]=read();
		for(int j=0;j<g[a[i]].size();j++) cnt[g[a[i]][j]]++;
	}
	for(int i=MX;i;i--){
		if(!cnt[i]) continue;
		if(cnt[i]>1) ans=max(ans,i);
		int pr=count(i);
		while(pr){
			if(__gcd(stk[top],i)==1) ans=max(ans,i*stk[top]),pr--;
			add(stk[top--],-1);
		}
		stk[++top]=i,add(i,1);
	}
	printf("%lld",ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值