gfoj测试题

题目:http://www.gdfzoj.com/oj/contest/256/problems/1

啊啊啊啊啊啊考虑漏了情况。。。

以后除了要用小数据去观察,还要用中等数据实验

code:

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

const int maxSize=10000000;
long long n,q,len,num=0,num1=0;
bool sss[maxSize+5];
int su[maxSize/2],ol[maxSize/2];

int gcd(int x,int y)//最大公约数 
{
	if (y!=0)
		return gcd(y,x%y);
	else
		return x;
}

void shai(int x)//素数筛 
{
	int i,j;
	
	for (i=2;i<=x;i++)
	{
		if (sss[i]==true)
			su[num++]=i;
		for (j=0;j<num;j++)
		{
			if (su[j]*i>x)	break;
			sss[su[j]*i]=false;
			if (i%su[j]==0)	break;
		}
	}
}

int oula(int x)//求长度 
{
	int i,ans=x;
	
	if (sss[x]==true)
		return x-1;
	for (i=0;i<num;i++)
	{
		if (su[i]>ceil(sqrt(x)))
			break;
		if (ans%su[i]==0)
			ans=(ans/su[i])*(su[i]-1);
	}
	return ans;
}

long long ksm(long long x,int y)//快速幂 
{
	long long ans;
	
	if (y==0)
		return 1;
	if (y==1)
		return x;
	ans=ksm(x,y/2)%n;
	if (y%2==0)
		return (ans*ans)%n;
	else
		return (((ans*ans)%n)*x)%n;
}

void zys(int x)//质因数 
{
	int i;
	
	for (i=0;i<num;i++)
		if (x%su[i]==0)
			ol[num1++]=su[i];
}

int main()
{
	long long i,a,j;
	
	freopen("a.txt","r",stdin);
	freopen("b,txt","w",stdout);
	scanf("%d%d",&n,&q);
	
	memset(sss,true,sizeof(sss));
	shai(n);
	len=oula(n);
	zys(len);
	for (i=0;i<q;i++)
	{
		scanf("%lld",&a);
		if (gcd(n,a)!=1 || a<=1)
		{
			printf("0");
			continue;
		}
		for (j=0;j<num1;j++)//循环质因数
		{
			if (ksm(a,len/ol[j])==1)//是除!!!
			{
				printf("0");
				break;
			}
		}
		if (j==num1 && ksm(a,len)==1)
			printf("1");
		else if (j==num1)
			printf("0");
//		if (j==num1)
//			printf("1");
	}
	
	return 0;
}


猜你喜欢

转载自blog.csdn.net/scutbenson/article/details/78499423