可以先写一个暴力 RMQ 解决 K=1 的 10 分代码,确保自己没读错题理解成字符串问题了囧。
那么 top K 可以用类似 [USACO3.1]丑数 Humble Numbers 那个题里的方法,开个堆,每次找到一个数就分裂一下塞回去。
这个题数据量足够大,询问数组的下标从 0 开始,还要询问 rmq 的位置,非常适合用我们新学习的 O(n)-O(1) RMQ 大显身手!。。。
#include <lastweapon/bitwise>
using namespace lastweapon;
const int N = int(5e5) + 9;
int s[N];
int n, K, L, R;
template<typename T> struct rmq {
vector<T> v; int n;
static const int b = 30; // block size
vector<int> mask, t; // mask and sparse table
int op(int x, int y) {
return v[x] < v[y] ? x : y;
}
// least significant set bit
int lsb(int x) {
return x & -x;
}
// index of the most significant set bit
int msb_index(int x) {
return __builtin_clz(1)-__builtin_clz(x);
}
// answer query of v[r-size+1..r] using the masks, given size <= b
int small(int r, int size = b) {
// get only 'size' least significant bits of the mask
// and then get the index of the msb of that
int dist_from_r = msb_index(mask[r] & ((1<<size)-1));
return r - dist_from_r;
}
rmq(){}
rmq(const vector<T>& v_) : v(v_), n(v.size()), mask(n), t(n) {
int curr_mask = 0;
for (int i = 0; i < n; i++) {
// shift mask by 1, keeping only the 'b' least significant bits
curr_mask = (curr_mask<<1) & ((1<<b)-1);
while (curr_mask > 0 and op(i, i - msb_index(lsb(curr_mask))) == i) {
// current value is smaller than the value represented by the
// last 1 in curr_mask, so we need to turn off that bit
curr_mask ^= lsb(curr_mask);
}
// append extra 1 to the mask
curr_mask |= 1;
mask[i] = curr_mask;
}
// build sparse table over the n/b blocks
// the sparse table is linearized, so what would be at
// table[j][i] is stored in table[(n/b)*j + i]
for (int i = 0; i < n/b; i++) t[i] = small(b*i+b-1);
for (int j = 1; (1<<j) <= n/b; j++) for (int i = 0; i+(1<<j) <= n/b; i++)
t[n/b*j+i] = op(t[n/b*(j-1)+i], t[n/b*(j-1)+i+(1<<(j-1))]);
}
// query(l, r) returns the actual minimum of v[l..r]
// to get the index, just change the first and last lines of the function
T query(int l, int r) {
// query too small
//if (r-l+1 <= b) return v[small(r, r-l+1)];
if (r-l+1 <= b) return small(r, r-l+1);
// get the minimum of the endpoints
// (there is no problem if the ranges overlap with the sparse table query)
int ans = op(small(l+b-1), small(r));
// 'x' and 'y' are the blocks we need to query over
int x = l/b+1, y = r/b-1;
if (x <= y) {
int j = msb_index(y-x+1);
ans = op(ans, op(t[n/b*j+x], t[n/b*j+y-(1<<j)+1]));
}
//return v[ans];
return ans;
}
};
rmq<int> T;
struct rec {
int i, l, r, m, f;
rec(int i, int l, int r) : i(i), l(l), r(r), m(T.query(l, r)) {
f = s[i] - s[m];
}
bool operator < (const rec& r) const {
return f < r.f;
}
};
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("/Users/minakokojima/Documents/GitHub/ACM-Training/Workspace/out.txt", "w", stdout);
#endif
RD(n, K, L, R);
VI a; a.PB(0);
REP_1(i, n) RD(s[i]) += s[i-1], a.PB(s[i]); a.pop_back();
T = rmq<int>(a);
priority_queue<rec> Q;
FOR_1(i, L, n) {
Q.push(rec(i, max(0, i-R), i-L));
}
LL z = 0; DO(K) {
auto u = Q.top(); Q.pop(); z += u.f;
if (u.m != u.l) Q.push(rec(u.i, u.l, u.m-1));
if (u.m != u.r) Q.push(rec(u.i, u.m+1, u.r));
}
cout << z << endl;
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
