超级钢琴
NOI2010
暴力30分
为了应对评论区清一色的屑,我特地把这个动图搬过来镇博,看在它的面子上,踩的轻点


变量解释放代码里了,就是那个maxsite用st维护保存的是最大值的位置,名字起得很贴切来着
思路大体就是暴力匹配,然后匹配到L到R里最大值,然后将L,R以选到的点pos对半分开继续匹配
#include <bits/stdc++.h> #define Re register int #define LL long long #define ki kiritokazuto //暴力被试过了MLE还有TLE的 //试一下 using namespace std; //这种写法有点小骚 /* inline void in(int &x) { int f = 0; x = 0; char c = getchar(); while(c < '0' || c > '9') f |= c == '-', c = getchar(); while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar(); x = f ? -x : x; }*/ namespace kiritokazuto{ template <typename T> inline void in(T &x) { int f = 0; x = 0; char c = getchar(); while(c < '0' || c > '9') f |= c == '-', c = getchar(); while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar(); x = f ? -x : x; } template <typename T> inline void ot(T x) { if (x < 0) putchar('-'), x = -x; if (x > 9) write(x / 10); putchar(x % 10 + '0'); } } using namespace kiritokazuto; namespace work{ #define Re register int #define LL long long #define ki kiritokazuto static const int maxn = 5e5 + 100000; static const int Inf = -2147483647; int n, m; int L, R; int sum[maxn], maxsite[maxn][20]; LL ans; struct Node { int l, r, L, R;//l起点,r终点(即是要选的点),L, R(终点的范围,为了给它劈开) bool operator < (const Node x) const{ return sum[r] - sum[l] < sum[x.r] - sum[x.l]; } }; int get_end(int l,int r){//找终点 if(r > n) r = n; if(l > r) return Inf;//不能劈了 if(l == r) return r; int k = 1; while((1 << k + 1) <= r - l) k++; if(sum[maxsite[l][k]] >= sum[maxsite[r - (1 << k) + 1][k]]) return maxsite[l][k]; return maxsite[r - (1 << k) + 1][k]; } priority_queue <Node> q; inline void MAIN() { in(n); in(m); in(L); in(R); for(Re i = 1, x; i <= n; i++){ in(x); sum[i] = sum[i-1] + x; maxsite[i][0] = i; } for(Re j = 1; (1 << j) <= n; j++) for(Re i = 1; i + (1 << j) - 1 <= n; i++) if(sum[maxsite[i][j-1]] >= sum[maxsite[i + (1 << j - 1)][j - 1]]) maxsite[i][j] = maxsite[i][j - 1]; else maxsite[i][j] = maxsite[i + (1 << j - 1)][j - 1]; for(Re i = 1; i + L - 1 <= n; i++) q.push((Node){i - 1, get_end(i + L - 1, min(i + R - 1, n)), i + L - 1, min(i + R - 1, n)}); for(Re i = 1; i <= m; i ++){ int l = q.top().l; int r = q.top().r; L = q.top().L; R = q.top().R; q.pop(); ans += sum[r] - sum[l]; if(r > L) q.push((Node){l, get_end(L, r - 1), L, r - 1}); //l........L .....r......R // 还能劈开左边 if(r < R) q.push((Node){l, get_end(r + 1, R), r + 1, R}); //l........L......r.......R // 还能劈开右边 } cout << ans; #undef ki } } signed main() { work :: MAIN(); }
愿你在冷铁卷刃之前,得以窥见天光

浙公网安备 33010602011771号