【題解】The Best Vacation
阿新 • • 發佈:2022-05-26
題目
題目連結 --> https://codeforces.com/contest/1358/problem/D
思路及程式碼實現
使勁想可以想到,在選擇一端連續的區間時,最划算的選擇應該是:
- 左端點選擇某個月的某個節點,右端點選擇某個月的月末
另外
-
由於可能跨年份,我們先把兩年拼接在一起
-
接著列舉每一個右端點
-
二分查詢滿足題意的左端點 -- 即找到一個最小的L,使得 sum [ r ] - sum [ l ] <= x
c++程式碼實現
#include <algorithm> #include <cmath> #include <cstring> #include <deque> #include <iostream> #include <map> #include <queue> #include <set> #include <sstream> #include <stack> #include <vector> #define all(x) x.begin(), x.end() #define lowbit(x) x&(-x) #define pb push_back #define int long long using namespace std; typedef unsigned long long ull; typedef long long ll; typedef pair<int, int> PII; const int N = 4e5 + 20; // int e[N], ne[N], h[N], idx; // char mp[N][N]; int n, x, num[N], a[N], b[N], s[N], c[N]; void solve() { cin >> n >> x; for (int i = 1; i <= n; i++) { cin >> a[i]; b[i] = (1 + a[i]) * a[i] / 2; s[i] = s[i - 1] + a[i]; //天數字首和 c[i] = c[i - 1] + b[i]; //代價字首和 } for (int i = 1; i <= n; i++) { a[n + i] = a[i], b[n + i] = b[i]; s[n + i] = s[n + i - 1] + a[n + i]; c[n + i] = c[n + i - 1] + b[n + i]; } n *= 2; int ans = -1; for (int i = 1; i <= n; i++) { if (s[i] < x) continue; int p = lower_bound(s + 1, s + n + 1, s[i] - x) - s; int tmp = c[i] - c[p]; int len = s[p] + x - s[i]; tmp += (a[p] + a[p] - len + 1) * len / 2; ans = max(ans, tmp); } cout << ans << endl; } signed main() { int tt = 1; // cin >> tt; while (tt--) solve(); return 0; }