Gym - 102056C(2018EC final) - CRT

题目链接:https://vjudge.net/problem/Gym-102056C

 

解题思路:

很明显是在200个字符串中存在一个最前面的位置是4*k,它的值自然是0,之后每隔+4依然是4的倍数,所以它的值也是0,那么在这200个字符串中,我们可以枚举4,9,,25,49,121,169这6个数,利用中国剩余定理(CRT)可以用六个式子解出待定解x,那么如何快速判断x是否是可行解呢?我们首先预处理出sqrt(n)中的质数,枚举质数p,找到200个数中是p的倍数的数,看他是否能整除p*p,如果可以就是0。筛法时间复杂度O(sqrt(x)*log(200))

 

还有一个关键是要判断解得组合数到达多少时一定是无解的。不然200全0,那么岂不是可以解出4*9*25*49*121*169个x?显然这样是会超时的,结果是当解得组合数大于10000时是无解的。(可以去打表试试,证明不来= =,另外我也觉得这个地方是这题有点搞的地方)

 

#include 
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int mx = 2e2 + 10;
const int a[] = {4,9,25,49,121,169};
int pri[mx*mx],M = 1,t[10];
int x,y,val[mx],q[mx*mx],head;
bool vis[mx*mx*3],mark[mx];
char str[mx];
vector  g[10];
void init()
{
	int top = 0,N = 1e5;
	for(int i=2;i10000) return 0*puts("-1"); 
	for(int i=0;i<6;i++) M *= a[i];
	for(int i=0;i<6;i++){
		int Mi = M / a[i];
		ex_euclid(Mi,a[i]);
		t[i] = (x+a[i])%a[i];
	}
	dfs(0,0);
	int ans = -1;
	sort(q,q+head); head = unique(q,q+head) - q;
	for(int i=0;i

 

你可能感兴趣的:(数论,思维题)