2020 HDU多校 第二场 06-The Oculus(斐波那契 + 哈希)

题目链接: 06-The Oculus

Description

题意:给出a, b, c的斐波那契01序列,求 c 序列中哪一位错误使得a*b != c

Let’s define the Fibonacci sequence F1,F2,… as F1=1,F2=2,Fi=Fi−1+Fi−2 (i≥3).

It’s well known that every positive integer x has its unique Fibonacci representation (b1,b2,…,bn) such that:

  • b1×F1+b2×F2+⋯+bn×Fn=x.
  • bn=1, and for each i (1≤i
  • For each i (1≤i

For example, 4=(1,0,1), 5=(0,0,0,1), and 20=(0,1,0,1,0,1) because 20=F2+F4+F6=2+5+13.

There are two positive integers A and B written in Fibonacci representation, Skywalkert calculated the product of A and B and written the result C in Fibonacci representation. Assume the Fibonacci representation of C is (b1,b2,…,bn), Little Q then selected a bit k (1≤k

It is so slow for Skywalkert to calculate the correct result again using Fast Fourier Transform and tedious reduction. Please help Skywalkert to find which bit k was modified.

Input

The first line of the input contains a single integer T (1≤T≤10000), the number of test cases.

For each case,

  • the first line of the input contains the Fibonacci representation of A
  • the second line contains the Fibonacci representation of B
  • and the third line contains the Fibonacci representation of modified C.

Each line starts with an integer n, denoting the length of the Fibonacci representation, followed by n integers b1,b2,…,bn, denoting the value of each bit.

It is guaranteed that:

  • 1≤|A|,|B|≤1000000.
  • 2≤|C|≤|A|+|B|+1.
  • ∑|A|,∑|B|≤5000000.

Output

For each test case, output a single line containing an integer, the value of k.

Sample Input

1
3 1 0 1
4 0 0 0 1
6 0 1 0 0 0 1

Sample Output

4

Method

  • 初做时误以为是需要从序列中找出乘法规律,补题时才焕然大悟,原来可以打表直接暴力解…
  • 先生成 斐波那契表 f[i] = f[i-1] + f[i-2], 范围是 1~2e6
  • 根据输入的a, b, c序列生成 _a, _b, _c.
  • 最后遍历 1 ~ n_a+n_b+1 (c最大长度范围),判断 dp[i] 是否满足 dp[i] = _a*_b - _c, 输出 i 即可。
  • 是不是很简单。。。

Code

详见注释

#include 
#include 

using namespace std;
#pragma GCC optimize(2)
#define Max 1000003 
#define ll long long

ll dp[2*Max];						//斐波那契打表 
int T, n_a, n_b, n_c, t;
ll _a, _b, _c;

int main()
{
	dp[1] = 1;
	dp[2] = 2;
	for(int i=3; i<Max*2; i++)
		dp[i] = dp[i-1] + dp[i-2];
	scanf("%d", &T);
	while(T--)
	{
		_a = _b = _c = 0;
		scanf("%d", &n_a);
		for(int i=1; i<=n_a; i++)
		{
			scanf("%d", &t);
			if(t) _a += dp[i];
		}
		scanf("%d", &n_b);
		for(int i=1; i<=n_b; i++)
		{
			scanf("%d", &t);
			if(t) _b += dp[i];
		}
		scanf("%d", &n_c);
		for(int i=1; i<=n_c; i++)
		{
			scanf("%d", &t);
			if(t) _c += dp[i];
		}
		ll temp = _a*_b-_c;
		for(int i=1; i<=n_a+n_b+1; i++)	//遍历dp[i] 
		{
			if(temp == dp[i]) {
				printf("%d\n", i);
				break;
			}
		}
	}
	return 0;
}


蒟蒻一只,欢迎指正

你可能感兴趣的:(训练赛病历,引理,&,技巧,&,NT,算法,哈希,c++)