【SCAU 10新生赛】 9511 跑跑卡丁车I 数论

某年暑假的时候,QIU很喜欢玩跑跑卡丁车,因为跑跑卡丁车能够在线联网,所以他就能跟自己的朋友一齐很开心的在同一跑道上比赛。
跑跑卡丁车的地图很多样,但是模式都差不多,在道具模式中,我们可以得到一些很有利的道具,帮助我们尽快的到达终点,或者妨碍对手前进。
为了简化模型,我们假设地图上只有一种道具(金币),如果你检了的话,你就可以增加自己的财富(¥¥),而地图中通常都有很多个点,很多条路,
每个点上存在不同的金币数量(不过捡了就没了),当你钱包的金币数达到一定的数量时,你就可以利用这些金币买到你喜欢的东西了_
当然,你肯定希望每一场得到的金币数目越多越好咯。
XUN也很喜欢这个游戏,由于对数学的爱好,XUN发现了另一个很好玩的玩法,对于每场比赛,她并不仅仅想知道自己赚了多少金币,她还想知道今天跟昨
天钱包的金币数量范围内,到底哪些神奇的数相差最小(最近),哪些神奇的数相差最大(最远)。
我们定义神奇的数为一些数,只能整除本身还有1。
由于QIU比较笨,不会回答XUN的问题,聪明的ACMER你能帮一下QIU吗?

输入格式
第一行,给出一个整数T,表示case数量
下面T行,每一行给出两个正整数L,R,L < R,R – L <=1000000,1 <= L < R <= 2147483647

输出格式
对于每一对L,R,输出最近的两个神奇的数,还有最远的两个神奇的数,如果没有相邻的两个神奇的数,输出”None.”
如果存在多对最近或最远的数,输出最小那对。

输入样例
2
21 987
78 80

输出样例
Closest: 29 31
Longest: 887 907
None.

题意:找出【L,R】区间内相邻最近和最远的质数,没有就输出none

思路:

和AcWing上一道“质数距离”的题一样,下面说一下思路:
1.任何一个合数都可以写成 n = p*q 的形式, 其中p<=根号n, q>=根号n。这个显然啦,一个数的因数分布在根号n两侧。
2.观察这个题,L,R各自的大小都能到2e9左右,就连最简单的线性筛都搞不到这么大,更别说其他什么暴力算法。
3.但是发现破题口在于区间长度:R-L+1 <= 1e6。这个地方怎么入手呢?诶,看看步骤1,这个区间内的所有合数都满足上述等式,那么,我们就可以把根号1e9以内的素数全部筛出来(这个普通线性筛很快就搞出来),然后用里面的每个素数去筛掉【L.R】里面的合数,那么剩下来的就是素数啦。

AC代码:

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(long long i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };

ll prime[maxn], tot = 0;
bool vis[maxn*10];
ll ans[maxn];

void init()
{
    prime[tot++] = 2; vis[4] = 1;
    for(int i=3; i<=maxn; i += 2)
    {
        if(!vis[i]) prime[tot++] = i;
        for(int j=0; j<tot&&prime[j]*i<=maxn; j++)
        {
            vis[i*prime[j]] = 1;
            if(i%prime[j]==0) break;
        }
    }
}

int main()
{
    init();
    ll L, R;
    int kase;
    cin>>kase;
    while(~scanf("%lld%lld",&L,&R))
    {
         mem(vis,0);
         rep(i,0,tot-1)     //外层遍历素数
         {
             if(prime[i]>R) break;      //如果当前这个超过区间上限就break掉
             ll cur = (L+prime[i]-1)/prime[i];      //这一步是找到[L,R]里面当前质数的最小倍数/该质数后的因子,其实就是L/prime[j]的向上取整
             for(ll j=cur; j*prime[i]<=R; j++)  if(j!=1)        //然后枚举倍数,从cur倍, 到cur+1倍,到cur+2倍,等等。直到超过区间边界
             vis[j*prime[i] -L] = 1;        //那么这个数j*prime[j]就是个合数啦,因为数很大,就-L这个偏移量,否则下标太大。
         }
         ll p = 0;
         ll dis = 1e12 , a = 0, b = 0 ;
         rep(i,L,R) if(!vis[i-L]&&i!=1) ans[++p] = i;
         if(p < 2) cout<<"None."<<'\n';
         else
         {
              rep(i,1,p-1) if(dis > abs(ans[i] - ans[i+1])) dis = abs(ans[i] - ans[i+1]) ,a = ans[i], b = ans[i+1];
              dis = 0; ll c = 0, d = 0;
              rep(i,1,p-1) if(dis < abs(ans[i] - ans[i+1])) dis = abs(ans[i] - ans[i+1]) ,c = ans[i], d = ans[i+1];
              printf("Closest: %lld %lld\n",a,b);
              printf("Longest: %lld %lld\n",c,d);
         }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45492531/article/details/107792981