一道题目
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;
}
By MYCui