【UOJ #20】【NOIP 2014】解方程

http://uoj.ac/problem/20

并不会做。。。然后看题解。。。。。。。

对a取模,避免了高精度带来的复杂度,然后再枚举x判断是否满足模意义下等于0。

取5个模数,我直接抄的别人的_(┐「ε:)_。时间复杂度$O(nm)$。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int p[5] = {11261,19997,22877,21893,14843};

char s[10003];
int n, m, a[5][103], cal[5][30003], ans[1000003], anslen = 0;

bool pd(int x) {
	for(int tmp = 0; tmp < 5; ++tmp)
		if (cal[tmp][x % p[tmp]] != 0) return false;
	return true;
}

int main() {
	scanf("%d%d", &n, &m);
	int len;
	bool fu;
	for(int i = 0; i <= n; ++i) {
		scanf("%s", s + 1);
		len = strlen(s + 1);
		fu = false;
		for(int tmp = 0; tmp < 5; ++tmp)
			if (s[1] == '-') {fu = true; a[tmp][i] = 0;}
			else a[tmp][i] = s[1] - '0';
		for(int tmp = 0; tmp < 5; ++tmp) {
			for(int j = 2; j <= len; ++j)
				a[tmp][i] = (a[tmp][i] * 10 + s[j] - '0') % p[tmp];
			if (fu) a[tmp][i] = -a[tmp][i];
		}
	}
	
	for(int tmp = 0; tmp < 5; ++tmp) {
		for(int x = 1; x <= p[tmp]; ++x) {
			int ret = a[tmp][n];
			for(int i = n - 1; i >= 0; --i)
				ret = (ret * x + a[tmp][i]) % p[tmp];
			cal[tmp][x] = ret;
		}
	}
	
	for(int i = 1; i <= m; ++i)
		if (pd(i))
			ans[++anslen] = i;
	
	printf("%d\n", anslen);
	for(int i = 1; i <= anslen; ++i)
		printf("%d\n", ans[i]);
	return 0;
}

_(:з」∠)_

posted @ 2016-08-26 17:28  abclzr  阅读(240)  评论(0编辑  收藏  举报