P5285骗分过样例——数论超级缝合怪
从等可以看出是
直接快速幂可过,加个欧拉定理就行。 这里都有写到
都是要猜模数,一个的想法就是找到输出数据中的最大值之后开始枚举模数,可以很快找到的模数。
虽然我在后面加个数就试出来了
就需要一点技巧了:
我选的方法如下:选择几对,并使得尽可能小。
可以知道为模数的倍数,所以用python
算几组数的最大公约数大致可以得到模数。
众所周知,乘法不开long long
会答案错误,而且有可能出现负数。
所以猜想这两组数据就是这样得到的,写个暴力就可以过
数据好大,而且快速幂的溢出是不对的(试试就知道了),怎么办呢?
这种可以由推至的可以试图找环,所以我们会想到用map
来辅助找环。
经试验,会在第项出现一个长度为的环。
根据小样例和输出的字母p
可以推出这部分是要筛出内的质数。
这部分很简单,大数据直接用米勒来宾测试判断质数就行
根据质数的地方都是-
,有平方因子的都是0
,字母u
,可以猜测这部分是计算内的莫比乌斯函数。
直接筛,是套路:筛出内的质数,枚举它们在区间的倍数,同时计算
只能筛到,还是枚举它们在区间的倍数。
可以想到有一部分数会有内的质数因子(最多有两个),可以这么处理:
枚举倍数的同时对每个算出它在内的质数因子的乘积(本身除掉的质数因子即可)。
枚举倍数后分三类讨论:
- 为完全平方数:
- 为质数:
- 以上两种都不是,这种情况一定是两个不同质数的乘积(或者是),不需要改的值
注意这部分可能被卡常。
众所周知:最小的原根是
根据这个和g
可以推断出是算出区间内的原根。
质数的原根满足:,用这个判断就行。
计算的所有原根,用的计算方式即可。
需要猜模数,我感觉没什么好的方法,就写了如下代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int MAXN=1000002;
bool np[MAXN];
int prime[MAXN],pcnt,mu[MAXN];
set<int>v;
const int p[]= {0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103},L=27;
inline ll mul(const ll&a,const ll&b,const ll&mod) {
ll r=((long double)a*b/mod+0.5);
r=a*b-r*mod;
return r<0?r+mod:r;
}
inline ull mr_fastpow(ull a,ull k,const ull&bigmod) {
ull base=1;
for(; k; k>>=1,a=mul(a,a,bigmod)) if(k&1)base=mul(base,a,bigmod);
return base;
}
inline bool mr(const ll n,const ll a) {
ll t=n-1;
while(!(t&1)) t>>=1;
ll buf=mr_fastpow(a,t,n);
if(buf==1||buf==n-1) return true;
while((t<<=1)<n-1) {
buf=mul(buf,buf,n);
if(buf==n-1) return true;
}
return false;
}
inline bool ptest(ll x) {
if(x==1) return false;
for(int i=1; i<=L; ++i)
if(!(x%p[i]))
return x==p[i];
return x<=10000ll?true:mr(x,2)&&mr(x,67)&&mr(x,233);
}
inline int fastpow(int a,int k,int mod) {
int base=1;
for(; k; k>>=1,a=a*1ll*a%mod) if(k&1)base=base*1ll*a%mod;
return base;
}
inline bool chker(int a,int P) {
int t=P-1;
for(int i=2; i*i<=t; ++i)
if(!(t%i)) {
t/=i;
if(fastpow(a,P/i,P)==1) return false;
while(!(t%i))t/=i;
}
if(t>1)if(fastpow(a,P/t,P)==1) return false;
return true;
}
//以上为米勒来宾质数测试
inline bool Chk(int x) {//判断x是否是质数且满足前11个数
return ptest(x)
&&!chker(233333333,x)
&&!chker(233333334,x)
&&!chker(233333335,x)
&& chker(233333336,x)
&& chker(233333337,x)
&& chker(233333338,x)
&&!chker(233333339,x)
&&!chker(233333340,x)
&& chker(233333341,x)
&& chker(233333342,x)
&&!chker(233333343,x);
}
inline bool Chk2(int x) {//判断x是否满足后20个数
for(int i=234133333,cnt=1; cnt<=20; ++cnt,--i)
if(chker(i,x)!=(cnt==3||cnt==8||cnt==10||cnt>18))
return false;
return true;
}
int a[100005],n;
int main() {
freopen("chk.txt","r",stdin);
freopen("chk.txt","w",stdout);
int l=1e9+1,r=2e9-1;
int cnt=0;
for(int i=l; i<=r; i+=2)//暴力枚举模数
if(Chk(i)&&Chk2(i))cout<<i<<endl;
return 0;
}
大约速通一次MC
的时间()就跑出来是,用的方法就做完了
代码也就有亿点难写。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】