F-Longest Common Subsequence
题目大意:
给出初始x和a,b,c,p,通过x=(a*x*x+b*x+c)%p不断更新的x构成长度n+m的序列,前n个数为一个序列,后m个数为另一个序列,问这两个序列的最长公共子序列长度
思路:
通过尝试发现,x=(a*x*x+b*x+c)%p不断生成的x序列总会生成已经出现过的x,而a,b,c,p是固定的,此后的x则进入了循环,所以长度为n和m的两个序列,一旦出现相同的数,则后面的数都是相同的
#include <bits/stdc++.h>
using namespace std;
const int N = 1000000;
long long s[N + 5], t[N + 5];
int main()
{
int caset, n, m;
long long p, a, b, c, x;
scanf("%d", &caset);
while(caset--)
{
map<long long, int> pos;
scanf("%d%d%lld%lld%lld%lld%lld", &n, &m, &p, &x, &a, &b, &c);
for (int i = 1; i <= n;i++)
{
s[i] = x = (a * x % p * x % p + b * x % p + c) % p;
if (pos.count(s[i]) == 0)
pos[s[i]] = i;
}
int ans = 0;
for (int i = 1; i <= m;i++)
{
t[i] = x = (a * x % p * x % p + b * x % p + c) % p;
if (pos.count(x))
ans = max(ans, min(m - i + 1, n - pos[x] + 1));
}
printf("%d\n", ans);
}
return 0;
}