1. 程式人生 > 實用技巧 >CF 1379 B. Dubious Cyrpto

CF 1379 B. Dubious Cyrpto

傳送門

題目:給定一個區間範圍[l, r]和m,在區間[l, r]中取a, b, c,使得 na + b - c = m(n > 0)。

思路:na + b - c = m,可以看出a和n都是整數,則:

na + b - c = m ->na = m - b + c

b,c∈[l, r] -> na ∈ [m + l - r, m + r - l]

則我們需要找到一個na存在於區間[m + l - r, m + r - l],a∈[l, r],我們可以列舉a,對於該a:

如果:①m / a * a >= m + l - r 且 m / a * a 一定滿足小於等於m,則我們把m - (m / a) * a用b,c∈[l, r]湊出來。

否則:②(m / a + 1) * a <= m + r - l 且 (m / a + 1) * a一定滿足大於等於m,則我們把m - (m / a + 1) * a用b,c∈[l, r]湊出來

當然有一種特殊情況:③ m < l,則直接 a = l, c = r, b = m - l + r

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <queue>
 5 #include <vector>
 6 #include <cmath>
 7
8 using namespace std; 9 10 #define ll long long 11 #define pb push_back 12 #define fi first 13 #define se second 14 15 const int N = 2e5 + 10; 16 char s[N]; 17 int len; 18 19 void solve() 20 { 21 int T; 22 cin >> T; 23 while(T--){ 24 25 ll l, r, m, a, b, c;
26 cin >> l >> r >> m; 27 28 if(m < l){ 29 a = l; 30 c = r; 31 b = m + r - l; 32 cout << a << " " << b << " " << c << endl; 33 continue; 34 } 35 36 ll ml = m + l - r; 37 ll mr = m + r - l; 38 for(int i = l; i <= r; ++i){ 39 ll times = m / i; 40 if(times * i < ml){ 41 if((times + 1) * i <= mr){ 42 a = i; 43 ll remains = (times + 1) * i - m; 44 b = l; 45 c = l + remains; 46 break; 47 } 48 }else if(times * i >= ml){ 49 ll remains = m - (times * i); 50 a = i; 51 b = r; 52 c = r - remains; 53 break; 54 } 55 } 56 57 cout << a << " " << b << " " << c << endl; 58 } 59 } 60 61 int main() 62 { 63 ios::sync_with_stdio(false); 64 cin.tie(0); 65 cout.tie(0); 66 solve(); 67 68 return 0; 69 }