[NOI2010]超级钢琴
自己演了自己,算错了主席树的空间,然后交上去直接就是个80,然后陷入深思,冷静思考了一会儿,意识到洛谷好像空间开小了会wa,于是加了个5,交上去就过了,以后要好好算空间。
//author Eterna #define Hello the_cruel_world! #pragma GCC optimize(2) #include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<utility> #include<cmath> #include<climits> #include<deque> #include<functional> #include<complex> #include<numeric> #include<unordered_map> #define Pi acos(-1.0) #define ABS(x) ((x) >= 0 ? (x) : (-(x))) #define pb(x) push_back(x) #define lowbit(x) (x & -x) #define FRIN freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\in.txt", "r", stdin) #define FROUT freopen("C:\\Users\\Administrator.MACHENI-KA32LTP\\Desktop\\out.txt", "w", stdout) #define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); #define outd(x) printf("%d\n", x) #define outld(x) printf("%lld\n", x) #define il inline using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const int maxn = 5e5; const int INF = 0x7fffffff; const int mod = 1e9 + 7; const double eps = 1e-7; inline int read_int() { char c; int ret = 0, sgn = 1; do { c = getchar(); } while ((c < '0' || c > '9') && c != '-'); if (c == '-') sgn = -1; else ret = c - '0'; while ((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0'); return sgn * ret; } inline ll read_ll() { char c; ll ret = 0, sgn = 1; do { c = getchar(); } while ((c < '0' || c > '9') && c != '-'); if (c == '-') sgn = -1; else ret = c - '0'; while ((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0'); return sgn * ret; } struct node { int L, R, cnt; }arr[25 * maxn + 5]; int T[maxn + 5], tot, sum[maxn + 5], pos[maxn + 5], cnt[maxn + 5], L[maxn + 5], R[maxn + 5]; int Build(int L, int R) { int index = ++tot; if (L < R) { int mid = L + R >> 1; arr[index].L = Build(L, mid); arr[index].R = Build(mid + 1, R); } return index; } int Update(int pre, int L, int R, int x) { int index = ++tot; arr[index] = arr[pre]; ++arr[index].cnt; if (L < R) { int mid = L + R >> 1; if (x <= mid)arr[index].L = Update(arr[pre].L, L, mid, x); else arr[index].R = Update(arr[pre].R, mid + 1, R, x); } return index; } int Query(int Left, int Right, int l, int r, int x) { if (l >= r)return l; int mid = l + r >> 1; int cnt = arr[arr[Right].L].cnt - arr[arr[Left].L].cnt; if (cnt >= x)return Query(arr[Left].L, arr[Right].L, l, mid, x); else return Query(arr[Left].R, arr[Right].R, mid + 1, r, x - cnt); } ll res; priority_queue<pii> q; int n, k, l, r, m; int main() { n = read_int() + 1, k = read_int(), l = read_int(), r = read_int(); L[1] = max(1, 1 - r); R[1] = 1 - l; for (int i = 2; i <= n; ++i) { sum[i] = read_int(); sum[i] += sum[i - 1]; pos[i] = sum[i]; L[i] = max(1, i - r); R[i] = i - l; } sort(pos + 1, pos + 1 + n); m = unique(pos + 1, pos + 1 + n) - pos - 1; T[0] = Build(1, m); for (int i = 1; i <= n; ++i) { int x = lower_bound(pos + 1, pos + 1 + m, sum[i]) - pos; T[i] = Update(T[i - 1], 1, m, x); } for (int i = 2; i <= n; ++i) { if (L[i] > R[i])continue; int x = pos[Query(T[L[i] - 1], T[R[i]], 1, m, 1)]; cnt[i] = 1; q.push(pii(sum[i] - x, i)); } for (int i = 1; i <= k; ++i) { pii now = q.top(); q.pop(); res += now.first; int p = now.second; ++cnt[p]; if (cnt[p] > R[p] - L[p] + 1)continue; int x = pos[Query(T[L[p] - 1], T[R[p]], 1, m, cnt[p])]; q.push(pii(sum[p] - x, p)); } cout << res << endl; //system("pause"); return 0; }
posted on 2019-03-17 16:15 Eterna_King 阅读(115) 评论(0) 编辑 收藏 举报