CF1285F Classical?

CF1285F Classical?

传送门

CodeForces

题解

一道比较神仙的题目吧.

你考虑枚举两个数\(x,y\),那么\(lcm(x,y)=\frac{xy}{gcd(x,y)}\)

我们枚举\(g=gcd(x,y)\),那么有\(ans=max(ans,x*y)\ [\gcd(x,y)=1]\)

所以可以直接枚举这个\(g\),然后只需要判断与它互质的数然后\(\text{check}\)答案即可.

问题在于怎么优化这个过程?考虑如果存在一个\(\gcd (x,y)=1\),那么对于\(x\)所有的\(x<z<y\)都不能产生贡献.

拿一个栈维护这个过程即可.

代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define REP(a,b,c) for(int a=b;a<=c;a++)
#define re register
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
typedef pair<int,int> pii;
#define mp make_pair
inline int gi()
{
	int f=1,sum=0;char ch=getchar();
	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
	return f*sum;
}
const int N=100010;
int n,a[N],m,mu[N],cnt[N],top,stk[N];
vector<int>g[N];
int main()
{
	n=gi();ll ans=0;
	for(int i=1,x;i<=n;i++)x=gi(),m=max(m,x),ans=m,a[x]=1;
	mu[1]=1;
	for(int i=1;i<=m;i++)
		for(int j=i+i;j<=m;j+=i)mu[j]-=mu[i];
	for(int i=1;i<=m;i++)
		for(int j=i;j<=m;j+=i)g[j].push_back(i),a[i]|=a[j];
	for(int i=m;i;i--)
		if(a[i])
		{
			int tot=0;
			for(int j:g[i])tot+=mu[j]*cnt[j];
			while(tot>0&&top)
			{
				int ret=tot;
				for(int j:g[stk[top]])
				{
					cnt[j]--;
					if(!(i%j))tot-=mu[j];
				}
				if(ret!=tot)ans=max(ans,1ll*i*stk[top]);
				top--;
			}
			for(int j:g[i])cnt[j]++;
			stk[++top]=i;
		}
	printf("%lld\n",ans);
	return 0;
}
posted @ 2020-05-11 14:26  fexuile  阅读(116)  评论(0编辑  收藏  举报