数学 赛码 1010 GCD

时间:2023-03-09 04:40:35
数学 赛码 1010 GCD

题目传送门

 /*
数学:官方题解
首先,数组中每个元素至少是1
然后对于任意一个询问Li, Ri, Ansi, 说明Li ~ Ri中的元素必定是Ansi的倍数,那么只需将其与Ansi取最小公倍数即可
如果在计算过程中有一个值超出了可行范围,那么就无解了
在计算完成之后,注意这个解并不一定是正确的,还需要对于所有询问检查一遍
时间复杂度O(NQlogX), X为值的范围
题目不难,算是签到题,可是队友考虑复杂了,GCD (0, ..) ?!
反思:题目要读仔细,组队时做不来要让队友帮忙读题想题
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <cmath>
#include <queue>
using namespace std; typedef long long LL; const int MAXN = 1e3 + ;
const int INF = 0x3f3f3f3f;
LL a[MAXN];
int l[MAXN], r[MAXN];
LL ans[MAXN]; LL GCD(LL a, LL b)
{
return b ? GCD (b, a % b) : a;
} LL LCM(LL a, LL b)
{
return a / GCD (a, b) * b;
} int main(void) //赛码 1010 GCD
{
//freopen ("J.in", "r", stdin); int t, n, q;
scanf ("%d", &t);
while (t--)
{
scanf ("%d%d", &n, &q);
for (int i=; i<=n; ++i) a[i] = ; bool flag = false;
for (int i=; i<=q; ++i)
{
scanf ("%d%d%I64d", &l[i], &r[i], &ans[i]);
for (int j=l[i]; j<=r[i]; ++j)
{
a[j] = LCM (a[j], ans[i]);
if (a[j] > 1e9)
{
flag = true; break;
}
}
} if (flag)
{
puts ("Stupid BrotherK!"); continue;
} for (int i=; i<=q; ++i)
{
LL k = a[l[i]];
for (int j=l[i]+; j<=r[i]; ++j)
{
k = GCD (k, a[j]);
}
if (k != ans[i])
{
flag = true; puts ("Stupid BrotherK!"); break;
}
} if (!flag) for (int i=; i<=n; ++i)
printf ("%I64d%c", a[i], (i==n) ? '\n' : ' ');
} return ;
} /*
Stupid BrotherK!
*/