一道題目
阿新 • • 發佈:2020-11-03
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(\(nlog(n)\) + \(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; }