P8219 [WFOI - 02] I wanna a feasitor(化验器)


题目传送门

思路:

设 $f(x)$ 表示除 $x$ 本身之外,$x$ 的最大约数

既然要求 $L \sim R$ 中的每一个数 $x$ , $f(x)$ 的最大值(后文简写为 $ans$ ),那么就有了第一种算法:暴力枚举

但是你会发现只有 $30$ 分, $T$ 飞了(甚至有几个点 $RE$ 了我也不知道为啥)

#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
int check(int x){
	for(int i=x-1;i>=2;i--){
		if(x%i==0)return i;
	}
}
int max(int x,int y){
	if(x>y)return x;
	else return y;
}
int l,r,maxx=0;
signed main(){
	cin>>l>>r;
	for(int i=l;i<=r;i++){
		maxx=max(maxx,check(i));
	}
	cout<<maxx<<endl;
	return 0;
}

那么我们就需要优化

先看测试数据:

$2 \leq L < R \leq 10^{18}$

因为 $L$ 到 $R$ 的区间包含 $L$ 和 $R$ ,由此可得:

$L$ 到 $R$ 的区间内至少包含两个连续整数

$\because$ 两个连续整数的奇偶性不一致

$\therefore$ 区间内必有一个偶数

$\therefore$ 当 $x$ 能被 $2$ 整除时, $f(x)=\frac{x}{2}$

又 $\because\frac{x+2}{2} \geq \frac{x}{2}$

$\therefore ans$ 的取值分两种情况:

  1. $R \bmod 2=0$ :$ans=\frac{R}{2}$
  2. $R \bmod 2=1$ :$ans=\frac{R-1}{2}$

那么代码就出来了:

#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
inline int read(){//快读优化
  	int x=0,f=1;
  	char c=getchar();
  	for(;c<'0'||c>'9';c=getchar())
    	if(c=='-')f=-1;
  	for(;c<='9'&&c>='0';c=getchar())
    	x=(x<<3)+(x<<1)+c-'0';
  	return x*f;
}
inline void out(int x){//输出优化
  	if(x>9)out(x/10);
  	putchar(x%10+'0');
}
int l,r;
signed main(){
	l=read(),r=read();	//输入区间
	out(r>>1);//输出 r/2 的值(因为 c++ 在整数除法中会自动向下取整,所以只需要输出 r/2 就可以了)
	return 0;//结束程序
}

文章作者: alex_liu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 alex_liu !
  目录