一道题目

Luogu比赛"小Z的 J-PCS 模拟赛"中有一道题目。(LC 比赛Rank 2 !!!!不愧是我们滴红太阳!!!太强哩!!!!) OOOOOrz

感觉这道题虽然水但是有点意思。

题意

就是求\(Max(i\) \(mod\) \(a\)) + (\(i\) \(mod\) \(b\))) 限定\(i\) ∈ 区间\([L,R]\)

给出\(a,b\)以及若干个询问,每个询问给出询问区间\([L,R]\)

\(1\) <= \(L,R\) <= \(10^9\) , 询问个数 <= \(10^6\), \(1\) <= \(a,b\) <= \(1000\)

这道题目的解法

\(GCD求LCM + ST\)表即可

求出\(a,b\)\(LCM\)然后暴力扩展,\(LCM(a,b)\) <= \(10^6\),然后对于每个询问用ST表即可.

时间复杂度:O(\(LCMlog(LCM)\) + \(q\) )

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000005;
int A[MAXN];
int Max[MAXN][22];
int gcd(int a,int b)
{
	if(a % b == 0)return b;
	else return gcd(b , a % b);
}

int LCM(int a,int b)
{
	return a*b/gcd(a,b);
}

inline int read()
{
	int x = 0 , flag = 1;
	char ch = getchar();
	for ( ; ch > '9' || ch < '0' ; ch = getchar())if(ch == '-')flag = -1;
	for ( ; ch >= '0' && ch <= '9' ; ch = getchar())x = (x << 3) + (x << 1) + ch - '0';
	return flag * x;
}

int GetMax(int l,int r)
{
	int k = log2(r - l + 1);
	return max(Max[l][k] , Max[r - (1 << k) + 1][k]);
}

int main()
{
	int a,b,n;
	a = read() , b = read();
	n = read();
	int lcm = LCM(a,b);
	for(int i = 1 ; i <= lcm ; i ++)
		A[i] = i % a + i % b,Max[i][0] = A[i];
	for(int j = 1 ; j <= log2(lcm) ; j ++)
		for(int i = 1 ; i + (1 << j) - 1<= lcm ; i ++)
	Max[i][j] = max(Max[i][j - 1] , Max[i + (1 << (j - 1))][j - 1]);
	for(int i = 1 ; i <= n ; i ++)
	{
		int l , r ,ll , rr;
		l = read() , r = read();
		if(r - l >= lcm)
		{
			cout << GetMax(1,lcm) << endl;
			continue;
		}
		ll = l , rr = r;
		l %= lcm;r %= lcm;
		if(l == 0) l = lcm;
		if(r == 0) r = lcm;
		if(l > r)
			cout << max( GetMax(l,lcm) , GetMax(1,r) ) << endl;
		else cout << GetMax( l , r ) << endl;
	}
	return 0;
}
posted @ 2020-11-03 19:47  MYCui  阅读(91)  评论(0编辑  收藏  举报