NOIP 2014 解方程 [模运算][哈希?]

 统计

已知多项式方程:

a0+a1x+a2x2+...+anxn=0

求这个方程在 [1,m] 内的整数解( n m均为正整数)。

输入格式

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

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

输出格式

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

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

样例一

input
2 10
1
-2
1

output
1
1

样例二

input
2 10
2
-3
1

output
2
1
2

样例三

input
2 10
1
3
2

output
0

限制与约定

对于30%的数据, 0<n2 |ai|100 an0 m100

对于50%的数据, 0<n100 |ai|10100 an0 m100

对于70%的数据, 0<n100 |ai|1010000 an0 m10000

对于100%的数据, 0<n100 |ai|1010000 an0 m1000000

时间限制: 1s

内存限制: 128MB

下载

样例数据下载


真不知道哈希是怎么想出来的

观察式子  只有加和乘运算  适用基础的模运算  所以   可以将系数取模且  F(n) = F(n % p)

可以预处理出 F(1) ~ F(p - 1) 对于一次询问只要将 n 模一下再查就好了

不够稳?  多来几个模数  选的好一点 可以少选


ID 题目 提交者 结果 用时 内存 语言 文件大小 提交时间 测评时间
#191031 #20. 【NOIP2014】解方程 Sakura_ 100 570ms 1380kb C++ 1.3kb 2017-09-12 17:23:41 2017-09-12 17:23:42
answer
#include <bits/stdc++.h>
using namespace std;

int n, m, mod[6] = {0, 9973, 8543, 7741};
int rat[4][105], as[4][100005], ss[1000005];
char s[10005];

int FP( int a, int b, int md )
{
	int ans = 1;
	while(b)
	{
		if(b & 1) ans = 1LL * ans * a % md;
		a = 1LL * a * a % md;
		b >>= 1;
	}
	return ans;
}

int F( int x, int k )
{
	int ans = 0, js = 1;
	for(int i = 0; i <= n; ++i, js = 1LL * js * x % mod[k])
		(ans += 1LL * js * rat[k][i + 1] % mod[k]) %= mod[k];
	return ans;
}

int main()
{
	cin >> n >> m;
	for(int i = 1, len; i <= n + 1; ++i)
	{
		scanf( "%s", s + 1 );
		len = strlen(s + 1);
		for(int k = 1, gg; k <= 3; ++k)
		{
			gg = 1;
			for(int j = 1; j <= len; ++j)
			{
				if(s[j] == '-')	gg = -1;
				else rat[k][i] = 1LL * rat[k][i] * 10 % mod[k] + s[j] - '0';
			}
			if(gg == -1) rat[k][i] = mod[k] - rat[k][i];
		}
	}
	for(int k = 1; k <= 3; ++k)
	{
		for(int i = 0; i <= min(mod[k] - 1, m); ++i)
			as[k][i] = F(i, k);
	}
	for(int i = 1; i <= m; ++i)
	{
		int pos1 = i % mod[1], pos2 = i % mod[2], pos3 = i % mod[3];
		if(as[1][pos1] == 0 && as[2][pos2] == 0 && as[3][pos3] == 0)
			ss[++ss[0]] = i;		
	}
	cout << ss[0] << endl;
	for(int i = 1; i <= ss[0]; ++i)
		printf( "%d\n", ss[i] );
	return 0;
}
/*
2 10
1
-2
1
*/
详细
小提示:点击横条可展开更详细的信息
Test #1:
score: 10
Accepted
time: 0ms
memory: 1272kb
Test #2:
score: 10
Accepted
time: 0ms
memory: 1240kb
Test #3:
score: 10
Accepted
time: 0ms
memory: 1272kb
Test #4:
score: 10
Accepted
time: 1ms
memory: 1276kb
Test #5:
score: 10
Accepted
time: 2ms
memory: 1272kb
Test #6:
score: 10
Accepted
time: 82ms
memory: 1380kb
Test #7:
score: 10
Accepted
time: 109ms
memory: 1380kb
Test #8:
score: 10
Accepted
time: 99ms
memory: 1380kb
Test #9:
score: 10
Accepted
time: 138ms
memory: 1380kb
Test #10:
score: 10
Accepted
time: 139ms
memory: 1376kb
Extra Test:
score: 0
Extra Test Passed

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值