LOJ3050
首先说明下每个点要干嘛:
1_998244353:求19的k次幂,对998244353取模,k可能很大,大到longlong装不下(真押韵)
1?(+):求19的k次幂,模数未知,要自己去猜,一个模数比较小,另一个很大,在longlong范围内
1wa_998244353:求19的k次幂,对998244353取模,但是观察输出数据发现有负数,再根据题目提示和wa判断是爆int了,k在longlong范围内
2p:区间判断质数,longlong范围内
2u:区间求
μ
\mu
μ,longlong范围内
2g:区间求是否是给出的数的原根
2g?:同2g,给出的数未知
Solution:
1_998244353:快速幂
对于k很大的情况,用费马小定理降幂
1?:首先求出输出文件里面最大的数是多少,然后往上枚举看是不是模数就行了
1?+:模数很大,但是我们可以找到
k
1
,
k
2
k1,k2
k1,k2,使
k
2
−
k
1
k2-k1
k2−k1尽量小,然后记下它们对应的答案为
a
n
s
1
,
a
n
s
2
ans1,ans2
ans1,ans2,则有
a
n
s
1
∗
1
9
k
2
−
k
1
≡
a
n
s
2
(
%
m
o
d
)
ans1*19^{k2-k1}\equiv ans2(\%mod)
ans1∗19k2−k1≡ans2(%mod)
a
n
s
1
∗
1
9
k
2
−
k
1
−
a
n
s
2
≡
0
(
%
m
o
d
)
ans1*19^{k2-k1}-ans2\equiv 0(\%mod)
ans1∗19k2−k1−ans2≡0(%mod)
然后mod就是前面那一堆的一个因数
多找几个这样的,求个gcd就行了
1wa_998244353:
直接用wa的办法乘,但是不能快速幂,k又很大
wa是有循环的,用个map找找循环就好了
2p:miller_rabin
2
μ
\mu
μ:首先筛出
1
−
1
e
6
1-1e6
1−1e6的质数,然后把区间的每个数的
1
−
1
e
6
1-1e6
1−1e6的因子筛掉
则剩下的部分要么是完全平方数,要么是质数,要么是两个大于1e6的质数乘起来,要么是1,miller_rabin下就好了
2g:第一个点直接暴力求原根
第二个点
13123111
−
1
=
2
∗
3
∗
5
∗
7
∗
11
∗
13
∗
19
∗
23
13123111-1=2*3*5*7*11*13*19*23
13123111−1=2∗3∗5∗7∗11∗13∗19∗23,筛一下不是原根的数
第三个点就暴力跑,猜p就好了
这题真是神题
Code:
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
using namespace std;
inline ll read(){
ll res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
char op[15];
inline ll mul(ll x,ll y,ll m){return (x*y-m*(ll)((long double)x*y/m+0.5)+m)%m;}
inline ll ksm(ll a,ll b,ll mod){ll res=1;for(;b;b>>=1,a=mul(a,a,mod)) if(b&1) res=mul(res,a,mod);return res;}
inline int wa_mul(register int a,int b,int mod){return a*b%mod;}
const int N=1e6+7;
int pt[N],pri[N],tot=0;
inline void init(){
pt[1]=1;
for(register int i=2;i<=N-7;++i){
if(!pt[i]) pri[++tot]=i;
for(register int j=1;j<=tot && i*pri[j]<=N-7;++j){
pt[i*pri[j]]=1;
if(i%pri[j]==0) break;
}
}
}
int prii[6]={0,2,3,5,7,29};
inline bool miller(ll x,int tim=5){
if(x<=N-7) return !pt[x];
if(x%2==0) return false;
ll t=x-1,s=0;
while(!(t&1)) ++s,t>>=1;
for(register int i=1;i<=tim;++i){
ll p=prii[i]%x;
ll num=ksm(p,t,x),tmp=num;
for(register int j=0;j<s;++j){
num=mul(num,num,x);
if(num==1 && tmp!=1 && tmp!=x-1) return false;
tmp=num;
}
if(num!=1) return false;
}
return true;
}
namespace l_998244353{
inline ll readk(register int mod){
ll res=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) {res=(mul(res,10,mod)+(ch^48))%mod;ch=getchar();}
return res;
}
inline void work(){
if(op[1]!='w'){
ll mod;
if(op[1]=='_') mod=998244353;
else if(op[1]=='?' && op[2]=='+') mod=5211600617818708273ll;
else mod=1145141;
int n=read();
while(n--){
ll k=readk(mod-1);
cout<<ksm(19,k,mod)<<"\n";
}
}
else{
map<int,int>mp;
vector<int>vec;
int st,ed;
vec.pb(1);
for(register int i=1,x=19;;++i,x=wa_mul(x,19,998244353)){
if(mp.find(x)==mp.end()) mp[x]=i,vec.pb(x);
else {st=mp[x],ed=i;break;}
}
int n=read();
while(n--){
ll x=read();
if(x<st) cout<<vec[x]<<"\n";
else cout<<vec[st+(x-st)%(ed-st)]<<"\n";
}
}
}
}
namespace two{
inline void p(){
int n=read();
while(n--){
ll l=read(),r=read();
for(ll i=l;i<=r;++i) miller(i)?putchar('p'):putchar('.');
puts("");
}
}
ll mu[N],tt[N];
inline void u(){
int n=read();
while(n--){
ll l=read(),r=read();
for(register int j=0;j<=r-l;++j) mu[j]=tt[j]=1;
for(register int j=1;j<=tot;++j){
for(ll k=l/pri[j];k<=r/pri[j];++k){
if(k*pri[j]-l<0) continue;
if(k%pri[j]) mu[k*pri[j]-l]*=-1,tt[k*pri[j]-l]*=pri[j];
else mu[k*pri[j]-l]=0;
}
}
for(ll j=l;j<=r;++j){
if(mu[j-l]){
ll x=j/tt[j-l];
if(x==1);
else if((ll)sqrt(x)*(ll)sqrt(x)==x) mu[j-l]=0;
else if(miller(x,1)) mu[j-l]*=-1;
}
if(!mu[j-l]) cout<<mu[j-l];
else putchar(mu[j-l]==1?'+':'-');
}
puts("");
}
}
int pt[13123122],f[13123122];
inline void g(){
int n=read(),mod;
while(n--){
int l=read(),r=read();
if(l==233333333) mod=1515343657;
else mod=read();
if(mod==998244353) for(register int i=l;i<=r;++i) (ksm(i,mod/2,mod)==1 || ksm(i,mod/7,mod)==1 || ksm(i,mod/17,mod)==1)?putchar('.'):putchar('g');
else if(mod==13123111){
for(register int i=1,g=6;i<mod;++i,g=g*6%mod) f[g]=i;
int p[]={2,3,5,7,11,13,19,23};
for(register int j=0;j<8;++j)
for(register int i=p[j];i<=mod;i+=p[j]) pt[i]=1;
for(register int i=l;i<=r;++i) pt[f[i]]?putchar('.'):putchar('g');
}
else for(register int i=l;i<=r;++i) (ksm(i,mod/2,mod)==1 || ksm(i,mod/3,mod)==1 || ksm(i,mod/4003,mod)==1 || ksm(i,mod/15773,mod)==1)?putchar('.'):putchar('g');
puts("");
}
}
}
int main(){
srand(time(0));
init();
cin>>op;
if(op[0]=='1') l_998244353::work();
else if(op[1]=='p') two::p();
else if(op[1]=='u') two::u();
else two::g();
return 0;
}