11
1
2015
1

【取模+枚举】NOIP2014 T6 解方程

CODEVS 3732: [NOIP2014]解方程

Time Limit: 1 Sec  Memory Limit: 128 MB

Description

Input

输入共n+2行。

第一行包含2个整数n、m,每两个整数之间用一个空格隔开。

接下来的n+1行每行包含一个整数,依次为a0,a1,a2,……,an

Output

第一行输出方程在[1, m]内的整数解的个数。

接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。

Hint

 

【数论噩梦系列】%%%数学省队同桌

--------------------------------0-------------------------------

妈呀这题我不会【滑稽再见】。

-------------------------------30-------------------------------

CCF的30%枚举拿拿还是很开心的【括弧笑】。

-------------------------------50-------------------------------

50%高精模拟?

听说某位线段树大师写挂了2333。

----------------------------思考人生----------------------------

怎么搞呢?

脑子想想都觉得100%高精不靠谱(高精加减乘方复杂度怎么看就愉♂悦)。

把范围缩小?

有没有听过这样一句话:由于XXXX的方案数太多,输出时要对100000007取模。

好熟悉的梗!

于是Get了一个新姿势:

-------------------------------70-------------------------------

选取几个较大素数(例如10000-20000之间的)

对于每个x,算出f(x)%pi,如果f(x)=0则f(x)%pi必然=0,多选几个素数,就可以在一定范围大小内判断成功。

但是不够快QAQ

-------------------------二段思考人生--------------------------

70拿拿也蛮好的,就当总分570做!

不对,这是练习,不是比赛现场。

搜题解:【定理:f(x)≡f(x+p)%p 这里f(x)为整系数多项式】

真TM机智!(二项式定理可以眼秒证明)

------------------------------100-------------------------------

对于一个x,f(x)≠0(mod p),则x+p,x+2p……均不为方程的解。

筛法大法好!

------------------------------150-------------------------------

m<=10^8

https://vijos.org/p/1915/solution @doc @sujiao

100分脑残Code:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define M 110
#define R 6
#define G getchar()
using namespace std;
int a[10005],A[M],P[R]={30011,11261,14843,19997,10007,21893},N,H[M][R],L,S=0,V,p,X,sum,x,n,m,W;
bool C[1000005];char ch;
int main()
{
	scanf("%d%d\n",&n,&m);
	for (int i=0;i<=n;i++)
	{
		L=0;
		if ((ch=G)=='-') N=-1;
		else a[L++]=ch-48,N=1;
		while ((ch=G)>47)a[L++]=ch-48;
		scanf("\n");
		for (int p=0;p<R;p++)
		{
			W=0;
			for (int w=0;w<L;w++)W=(W*10+a[w])%P[p];
			H[i][p]=(P[p]+W*N)%P[p];
		} 
	}
	for (int i=1;i<=m;i++)
	{
		V=1;
		if (C[i]) continue;
		for (int j=0;j<R;j++)
		{
			p=P[j],x=i%p,sum=0,X=1;
			for (int k=0;k<=n;k++) sum=(sum+X*H[k][j])%p,X=(X*x)%p;	
			if (sum)
			{
				for (int k=i;k<=m;k+=P[j])C[k]=1;
				V=0;break;
			}
		}
		if (V) A[++S]=i;
	}
	printf("%d\n",S);
	for (int i=1;i<=S;i++)
		printf("%d\n",A[i]);
	return 0;
}

150分Code:(由于O(n^3+n*sqrt(m))导致常规数据下比O(m)慢)

 

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define maxn 110
#define pri 4
using namespace std;
typedef long long LL;
int a[10010],prime[4]={10007,10009,12007,13001},neg,hehe[110][4],l;
int s[110][2],la[2],anss[110],ans;
char ch;
void gcd(LL a,LL b,LL& d,LL& x,LL &y)//ax+by=d
{
	if (!b)d=a,x=1,y=0;
	else gcd(b,a%b,d,y,x),y-=x*(a/b);
}
LL CRT(LL a1,LL p1,LL a2,LL p2)//%a1=p1 %a2=p2
{
	LL s=a2-a1,k1,k2,pp=p1*p2,d;
	gcd(p1,-p2,d,k1,k2);
	s=(s%pp+pp)%pp;
	k1=(k1%pp+pp)%pp;
	//d=1;
	k1=k1*s%pp;
	return (k1*p1%pp+a1%pp)%pp;
}
int main()
{
	int n,m;
	scanf("%d%d\n",&n,&m);
	for (int i=0;i<=n;i++)
	{
		l=0;
		ch=getchar();
		if (ch=='-') neg=-1;
		else {a[l++]=ch-48;neg=1;}
		ch=getchar();
		while (ch<=57&&ch>=48)
		{
			a[l++]=ch-48;
			ch=getchar();
		}
		scanf("\n");
		for (int p=0;p<pri;p++)
		{
			int ans=0;
			for (int w=0;w<l;w++)
				ans=(ans*10+a[w])%prime[p];
			hehe[i][p]=(prime[p]+ans*neg)%prime[p];
		} 
	}
	int ans=0;
	for(int A=0;A<2;A++)
	{
		for (int i=1;i<=prime[A];i++)//枚举答案 
		{
			int p=prime[A],x=i%p,sum=0,X=1;
			for (int k=0;k<=n;k++)//
				sum=(sum+X*hehe[k][A])%p,X=(X*x)%p;	
			if (!sum) {s[++la[A]][A]=i;}
		}
	}
	for(int I=1;I<=la[0];I++)
		for(int J=1;J<=la[1];J++)
		{
			int vic=1,i=CRT(s[I][0],prime[0],s[J][1],prime[1]);
			if(i>m)continue;
			for (int j=0;j<pri;j++)//判素数 
			{
				int p=prime[j],x=i%p,sum=0,X=1;
				for (int k=0;k<=n;k++)//
					sum=(sum+X*hehe[k][j])%p,X=(X*x)%p;	
				if (sum)
				{
					vic=0;
					break;
				}
			}
			if (vic) {anss[++ans]=i;}
		}
	if(!ans)puts("0");
	else
	{
		sort(anss+1,anss+1+ans);
		printf("%d\n",ans);
		for (int i=1;i<=ans;i++)
			printf("%d\n",anss[i]);
	}
	return 0;
}
Category: NOIP | Tags: 数论 枚举 模意义 | Read Count: 826
Avatar_small
q234rty 说:
2015年11月05日 21:44

%%%快去做解方程加强版!
https://vijos.org/p/1915


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com