CF-CodeCraft-20-Div. 2-C题

CF-CodeCraft-20-Div. 2-C题

C. Primitive Primes

传送门

数学问题。
题目给你两组多项式和一个素数。
让你任意输出一个两个多项式相乘之后系数不能整除所给素数的指数

暴力是不可能了。一看就会tle。
很容易知道如果两个数都不能整除一个素数。那么他们的乘积也不能整除。
我们把a[i]作为第一个不能整除素数的那个数
b[j]作为第一个不能整除素数的那个数
那么a[0]~a[i-1]都可以被素数p整除
b[0]~b[j - 1]也可以都被素数p整除

所以式子
x^(i+j)(这里求的是以i+j为指数的系数) = a[0]*b[i+j] + a[1] * b[i+j-1] +…+ a[i] * b[j] + a[i+1]*b[j-1]+a[i+2]*b[j-2]+…
左半部分a[0]*b[i+j] + a[1] * b[i+j-1] 可以整除p
右半部分a[i+1]*b[j-1]+a[i+2]*b[j-2]+…也可以整除p

a[i]*b[j]就不能整除p
所以我们只要找到第一个多项式中第一个不能整除p的那个指数
找到第二个多项式中第一个不能整除p的那个指数
然后把他们相加就可以输出啦~

有人可能会问为啥一定是第一个,第二个或者第三个不行吗?
答案:不行

这里提供hack你的一组数据:
5 5 5

0 1 0 3 0

0 2 0 4 0
a[3]和b[1]都不能整除5。但是3+1=4的答案并不是正确的
因为求指数为4的系数:a[0]*b[4]+a[1]*b[3]+a[2]*b[2]+a[3]*b[1]+a[4]*b[0]=10
10可以整除5,wa

代码部分:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll n, m, p;
ll x, y;

int main()
{
	cin >> n >> m >> p;
	int flag = 0;
	int cnt = 0;
	for (int i = 0; i < n; i++)
	{
		scanf ("%I64d", &x);
		if (x % p && !flag)
		{
			cnt = i;
			flag = 1;
		}
	}
	flag = 0;
	for (int i = 0; i < m; i++)
	{
		scanf ("%I64d", &y);
		if (y % p && !flag)
		{
			cnt += i;
			flag = 1;
		}
	}
	cout << cnt << endl;
	return 0;
}
发布了112 篇原创文章 · 获赞 3 · 访问量 2649

猜你喜欢

转载自blog.csdn.net/qq_44624316/article/details/104867392