HDU-6273-Master of GCD(差分數組)

題目描述

Hakase has n numbers in a line. At fi rst, they are all equal to 1. Besides, Hakase is interested in primes. She will choose a continuous subsequence [l, r] and a prime parameter x each time and for every l≤i≤r, she will change ai into ai*x. To simplify the problem, x will be 2 or 3. After m operations, Hakase wants to know what is the greatest common divisor of all the numbers.

輸入
The first line contains an integer T (1≤T≤10) representing the number of test cases.
For each test case, the fi rst line contains two integers n (1≤n≤100000) and m (1≤m≤100000),where n refers to the length of the whole sequence and m means there are m operations.
The following m lines, each line contains three integers li (1≤li≤n), ri (1≤ri≤n), xi (xi∈{2,3} ),which are referred above.

輸出
For each test case, print an integer in one line, representing the greatest common divisor of the sequence. Due to the answer might be very large, print the answer modulo 998244353.

樣例輸入

2
5 3
1 3 2
3 5 2
1 5 3
6 3
1 2 2
5 6 2
1 6 2

樣例輸出

6
2

提示
For the first test case, after all operations, the numbers will be [6,6,12,6,6]. So the greatest common divisor is 6.

題目大意

先給一個T,有T組查詢,然後每組數據長度爲 n ,且區間內的每一個數都是1,然後一共有 m 組數據,每組爲L R X;這個[L ,R]閉區間內的數都乘以 X; 問你最後這一串數字的最大公約數,並且最後結果對 998244353取模;

解題思路

這個題就是一個差分數組,因爲這數列的最大公約數就是這個數列 2 的 出現 2的最少次數的冪 乘以 3 的出現3的最少次數的冪 將2和3分開討論,然後分別記錄這個區間內最少出現了幾次2或3;再利用矩陣快速冪進行計算,最後把兩個結果相乘再取模就行了;

#include<iostream>
#include<algorithm>

using namespace std;
#define ll long long
const int maxn=1e5+10;
const int mod=998244353;
ll a[maxn],b[maxn],c[maxn];
//矩陣快速冪 
ll poww(ll x,ll y)
{
	ll da=1;
	while(y)
	{
		if(y&1) da=(da*x)%mod;
		x=x*x%mod;
		y>>=1;
	}
	return da;
}

int main()
{
	ios::sync_with_stdio(false);
	int t,m,n;
	ll x,y,z;
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		for(int i=0;i<=n;i++) b[i]=c[i]=0;
// 數組 b[]記錄 2;的情況
// 數組 c[]記錄3;的情況 
 		while(m--)
		{
			cin>>x>>y>>z;
// 差分的關鍵代碼			
			if(z==2)
			{
				b[x]++,b[y+1]--;
			}
			else c[x]++,c[y+1]--;
		}
		ll sum=0;
		ll ans,ans2;
		ans2=ans=10000000;
// 記錄這個數組內最少出現了多少 2  
		for(int i=1;i<=n;i++)
		{
			sum+=b[i];
			ans=ans<sum?ans:sum;
		}
// 記錄這個數組內最少出現了多少 3 	
		sum=0;
		for(int i=1;i<=n;i++)
		{
			sum+=c[i];
			ans2=ans2<sum?ans2:sum;
		}
//分別求 2 和 3 的冪然後相乘		
		sum=poww(2,ans);
		ans=sum%mod*(poww(3,ans2))%mod;
		cout<<ans<<"\n";
	}
	return 0;
}
/*
2
5 3
1 3 2
3 5 2
1 5 3
6 3 
1 2 2
5 6 2
1 6 2
*/
發佈了54 篇原創文章 · 獲贊 16 · 訪問量 4996
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章