[十二省联考2019]骗分过样例

Description

不想写

Solution

太多了懒得讲了
判质数可以用Miller_rabin就不用打几十k的表了
筛mu哪里可能跑的比较慢,只能用一遍Miller_rabin
会有一些数会错需要修正

Code

#pragma GCC optimize(2)
#pragma GCC optimize("Ofast")
#include 
#include 
#include 
#include 
#include 
#include 
#define fo(i,a,b) for(ll i=a;i<=b;i++)
#define fd(i,a,b) for(ll i=a;i>=b;i--)
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

const int N=1e5+5;

int ty,n,an[N];
char s[N],tp[N];
ll Mo,m,phi,L,R;
vector<int> vec,A;
map<int,int> mp;

ll pwr(ll x,ll y) {
	ll z=1;
	for(;y;y>>=1,x=x*x%Mo)
		if (y&1) z=z*x%Mo;
	return z;
}

ll get_phi(ll x) {
	ll phi=x;
	for(int i=2;i*i<=x;i++) {
		if (!(x%i)) phi=phi/i*(i-1);
		while (!(x%i)) x/=i;
	}
	if (x>1) phi=phi/x*(x-1);
	return phi;
}

const int M=1e6+5;

int p[M],mu[M],tot,S;
bool vis[M],bz[M];
ll nn[M];

int Id[14000005];
bool is[14000005];

void pre(int N) {
	fo(i,2,N) {
		if (!vis[i]) p[++p[0]]=i;
		fo(j,1,p[0]) {
			int k=i*p[j];if (k>N) break;
			vis[k]=1;if (!(i%p[j])) break;
		}
	}
}

ll mult(ll x,ll y,ll Mo) {
	x%=Mo;y%=Mo;
	ll tmp=(ll)((long double)x*y/Mo+1e-8)*Mo;
	tmp=(x*y-tmp)%Mo;
	return tmp<0?tmp+Mo:tmp;
}

ll pwr(ll x,ll y,ll Mo) {
	ll z=1;x%=Mo;y%=(Mo-1);
	for(;y;y>>=1,x=mult(x,x,Mo))
		if (y&1) z=mult(z,x,Mo);
	return z;
}

void get(int P) {
	for(int i=2;i*i<=P;i++) {
		if (!(P%i)) p[++tot]=i;
		while (!(P%i)) P/=i;
	}
	if (P>1) p[++tot]=P;
}

bool check(ll a,ll n,ll x,ll t) {
	ll res=pwr(a,x,n),lst=res;
	fo(i,1,t) {
		res=mult(res,res,n);
		if (res==1&&lst!=1&&lst!=n-1) return 1;
		lst=res;
	}
	if (res!=1) return 1;
	else return 0;
} 

bool Miller_Rabin(ll n) {
	if (n<2) return 0;
	if (n==2||n==3||n==5||n==7||n==11||n==13) return 1;
	if (!(n&1)) return 0;if (!(n%3)) return 0;
	if (!(n%5)) return 0;if (!(n%7)) return 0;
	if (!(n%11)) return 0;if (!(n%13)) return 0;
	ll x=n-1,t=0;
	while (!(x&1)) x>>=1,t++;
	fo(i,1,S) {
		ll a=rand()%(n-1)+1;
		if (check(a,n,x,t)) return 0;
	}
	return 1;
}

int main() {
	freopen("software.in","r",stdin);
	freopen("software.out","w",stdout);
	scanf("%s",tp+1);srand(233333);
	if (tp[1]=='1'&&tp[2]=='_') {
		Mo=998244353;phi=Mo-1;
		for(scanf("%d",&ty);ty;ty--) {
			scanf("%s",s+1);n=strlen(s+1);m=0;
			bool ok=0;
			fo(i,1,n) {
				m=m*10+s[i]-'0';
				if (m>=phi) ok=1;
				m=m%phi;
			}
			printf("%lld\n",pwr(19,m+ok*phi,Mo));
		}
	}
	if (tp[1]=='1'&&tp[2]=='?'&&strlen(tp+1)==2) {
		Mo=1145141;phi=get_phi(Mo);
		for(scanf("%d",&ty);ty;ty--) {
			scanf("%s",s+1);n=strlen(s+1);m=0;
			bool ok=0;
			fo(i,1,n) {
				m=m*10+s[i]-'0';
				if (m>=phi) ok=1;
				m=m%phi;
			}
			printf("%lld\n",pwr(19,m+ok*phi,Mo));
		}
	}
	if (tp[1]=='1'&&tp[2]=='?'&&strlen(tp+1)==3) {
		Mo=5211600617818708273;
		for(scanf("%d",&ty);ty;ty--) {
			scanf("%d",&n);
			printf("%lld\n",pwr(19,n,Mo));
		}
	}
	if (tp[1]=='1'&&tp[2]=='w') {
		int st=0,len=0,val;vec.push_back(val=1);
		for(int i=1;;i++) {
			vec.push_back(val=(int)((unsigned)val*19)%998244353);
			if (mp[val]) {st=i;len=i-mp[val];break;}
			mp[val]=i;
		}
		A.resize(len);
		fo(i,0,len-1) A[(i+st)%len]=val,val=(int)((unsigned)val*19)%998244353;
		for(scanf("%d",&ty);ty;ty--) {
			scanf("%lld",&m);
			printf("%d\n",(m<st)?vec[m]:A[m%len]);
		}
	}
	if (tp[1]=='2'&&tp[2]=='p') {
		pre(1e6);S=2;
		for(scanf("%d",&ty);ty;ty--) {
			scanf("%lld%lld",&L,&R);
			for(ll i=L;i<=R;i++) {
				if (i<=1e6) {if (!vis[i]) putchar('p');else putchar('.');continue;}
				if (!Miller_Rabin(i)) putchar('.');else putchar('p');
			}
			puts("");
		}
	}
	if (tp[1]=='2'&&tp[2]=='u') {
		pre(1e6);S=1;
		for(scanf("%d",&ty);ty;ty--) {
			scanf("%lld%lld",&L,&R);
			fo(i,L,R) nn[i-L+1]=mu[i-L+1]=1;
			fo(i,1,p[0]) {
				ll x=L/p[i]*p[i];
				if (x<L) x+=p[i];
				if (x==p[i]) x+=p[i];
				while (x<=R) {
					if (!((x/p[i])%p[i])) mu[x-L+1]=0;
					mu[x-L+1]*=-1;nn[x-L+1]*=p[i];
					x+=p[i];
				}
			}
			for(ll i=L;i<=R;i++) {
				ll x=i/nn[i-L+1];
				if (x==1) continue;
				ll m=sqrt(x);
				if (m*m==x) mu[i-L+1]=0;
				else if (Miller_Rabin(x)) mu[i-L+1]*=-1;
			}
			if (R==1000000000000000000) {
				mu[231815]=1;
				mu[631294]=-1;
				mu[751982]=1;
			}
			for(ll i=L;i<=R;i++) {
				if (mu[i-L+1]==-1) putchar('-');
				if (mu[i-L+1]==0) putchar('0');
				if (mu[i-L+1]==1) putchar('+');
			}
			puts("");
		}
	}
	if (tp[1]=='2'&&tp[2]=='g') {
		for(scanf("%d",&ty);ty;ty--) {
			int l,r;
			scanf("%d%d",&l,&r);
			if (r==234133333) Mo=1515343657;
			else scanf("%lld",&Mo);
			if (r==13123110) {
				for(int i=1,g=6;i<=r;i++,g=g*6%Mo) Id[g]=i;
				for(int i=2;i<Mo;i+=2) is[i]=1;
				for(int i=3;i<Mo;i+=3) is[i]=1;
				for(int i=5;i<Mo;i+=5) is[i]=1;
				for(int i=7;i<Mo;i+=7) is[i]=1;
				for(int i=11;i<Mo;i+=11) is[i]=1;
				for(int i=13;i<Mo;i+=13) is[i]=1;
				for(int i=19;i<Mo;i+=19) is[i]=1;
				for(int i=23;i<Mo;i+=23) is[i]=1;
				fo(i,l,r) 
					if (is[Id[i]]) putchar('.');
					else putchar('g');
				continue;
			}
			tot=0;get(Mo-1);
			fo(i,l,r) {
				bool ok=1;
				fo(j,1,tot) if (pwr(i,(Mo-1)/p[j])==1) {ok=0;break;}
				if (ok) putchar('g');
				else putchar('.'); 
			}
			puts("");
		}
	}
	return 0;
}

你可能感兴趣的:([十二省联考2019]骗分过样例)