"蔚来杯"2022牛客暑期多校训练营8
F-Longest Common Subsequence
题目大意
给定 p , x , a , b , c p,x,a,b,c p,x,a,b,c,求出长度为 n n n 的序列 s s s 和长度为 m m m 的序列 t t t 的最长公共子序列,其中 s s s 和 t t t 两个序列由 ( a x 2 + b x + c ) m o d p (ax^2+bx+c)\ mod\ p (ax2+bx+c) mod p 生成。
思路
打表(或由取模的性质)可发现存在循环节,即如果两个序列中出现了相同的数字,那么后面的数字一定全部一样。因此先记录 s s s 中每个数字最先出现的位置 p p p,遍历 t t t,当遇到 s s s 中出现过的数字时,用 m i n ( m − i + 1 , n − p + 1 ) min(m-i+1,n-p+1) min(m−i+1,n−p+1) 更新答案。
代码
void solve() {
scanf("%d%d%d%d%d%d%d", &n, &m, &p, &x, &a, &b, &c);
std::map<int, int> mp;
for (int i = 1; i <= n; i++) {
x = ((1LL * a * x % p * x % p + 1LL * b * x % p) % p + c) % p;
if (!mp.count(x)) mp[x] = i;
}
int ans = 0;
for (int i = 1; i <= m; i++) {
x = ((1LL * a * x % p * x % p + 1LL * b * x % p) % p + c) % p;
if (mp.count(x)) ans = std::max(ans, std::min(m - i + 1, n - mp[x] + 1));
}
printf("%d\n", ans);
}