HDU-6273 Master of GCD (application of prime factorization theorem)
Title:
- Give T group data
- Enter n and m in the first row of each group of data, which means that m operations are performed on an array with a length of n and an initial value of 1
- Input three numbers L, R, op for each operation, op can only be 2 or 3, which means each number in the interval from L to R a[i] = a[i] * op ,i=2,3
- What is the greatest common divisor of these n numbers after m operations?
Ideas:
- To find the greatest common divisor of n numbers, you can decompose these n numbers into prime factors, and then find all the prime factors a and the smallest power p of the prime factors that have appeared in the n decomposition formulas, and then Multiplying all a p is the greatest common divisor
- From the meaning of the question, the initial value of each number is 1, and the prime factor can only be 2 or 3. So recording how many times a[i] is multiplied by 2 and how many times 3 is equivalent to decomposing a[i] into prime factors , And finally count the smallest power of 2 and the smallest power of 3 and then multiply them (fast powers can be used, remember to take the remainder)
- How to count how many times a[i] is multiplied by 2 and 3? I use the idea of scanning lines, use the book array to count, book[L]++, book[R+1]–, and finally calculate the prefix sum
撸Code:
#include<math.h>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
long long book[4][100010];
long long mod=998244353;
ll Quick_Power(ll a,ll b)//快速幂
{
ll res = 1;
a %= mod;
while(b){
if(b&1){
res = (res * a) % mod;
}
a = (a * a) % mod;
b >>= 1;
}
return res%mod;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=n+1;i++){
book[2][i]=book[3][i]=0;
}
int r,l,tag;
for(int i=0;i<m;i++){
scanf("%d%d%d",&l,&r,&tag);
book[tag][l]++;
book[tag][r+1]--;
}
for(int i=1;i<=n;i++){
book[2][i]+=book[2][i-1];
book[3][i]+=book[3][i-1];
/*由于初始值为 1 ,所以每个数的素因子只有 2 和 3 ,
通过该步骤得出每个数的素因子的幂次,找到2的最小幂次 和 3 的最小幂次,
乘积就是最大公约数 */
// printf("%d | %d\n",book[2][i],book[3][i]);
}
long long mina=0x3f3f3f3f,minb=0x3f3f3f3f;
for(int i=1;i<=n;i++){
mina=min(mina,book[2][i]);
minb=min(minb,book[3][i]);
}
long long temp1=Quick_Power(2,mina);
long long temp2=Quick_Power(3,minb);
printf("%lld\n",(temp1*temp2)%mod);
}
return 0;
}