UOJ386【UNR #3】鴿子固定器【ad-hoc,連結串列】
阿新 • • 發佈:2021-06-25
給定 \(n\) 個二元組 \((s_i,v_i)\) 和正整數 \(d_s,d_v\),求選擇 \(m\) 個二元組的 \((\sum v)^{d_v}-(\max s-\min s)^{d_s}\) 的最大值。
\(n\le 2\cdot 10^5\),\(m\le 50\),\(d_s,d_v\le 2\),\(1\le s_i,v_i\le 10^7\)。
顯然按 \(s\) 排序之後就變成了選一個區間 \([l,r]\),貢獻是這一段的前 \(m\) 大的 \(v\) 之和的 \(d_v\) 減去 \((s_r-s_l)^{d_s}\)。
然後就被教育了:先列舉所有長度 \(\le m\)
時間複雜度 \(O(nm)\)。
#include<bits/stdc++.h> #define fi first #define se second using namespace std; typedef pair<int, int> pii; typedef long long LL; const int N = 200003, M = 103; template<typename T> void rd(T &x){ int ch = getchar(); x = 0; for(;ch < '0' || ch > '9';ch = getchar()); for(;ch >= '0' && ch <= '9';ch = getchar()) x = x * 10 + ch - '0'; } template<typename T> bool chmax(T &a, const T &b){if(a < b) return a = b, 1; return 0;} int n, m, k, ds, dv, id[N], lst[N], nxt[N], b[M]; pii a[N]; LL ans, sum[M]; LL valv(LL v){return dv == 1 ? v : v * v;} LL vals(LL s){return ds == 1 ? s : s * s;} int main(){ rd(n); rd(m); rd(ds); rd(dv); for(int i = 1;i <= n;++ i){ rd(a[i].fi); rd(a[i].se); } sort(a+1, a+n+1); for(int i = 1;i <= n;++ i){ LL s = a[i].se; for(int j = i;j < i+m && j <= n;s += a[++j].se) chmax(ans, valv(s) - vals(a[j].fi-a[i].fi)); } for(int i = 1;i <= n;++ i){ lst[i] = i-1; nxt[i] = i+1; id[i] = i; } sort(id+1, id+n+1, [&](int x, int y){return a[x].se==a[y].se ? x<y : a[x].se<a[y].se;}); for(int _ = 1;_ <= n-m+1;++ _){ k = 0; int i = id[_]; for(int j = 1, p = lst[i];j < m && p;++ j, p = lst[p]) b[++k] = p; reverse(b+1, b+k+1); b[++k] = i; for(int j = 1, p = nxt[i];j < m && p <= n;++ j, p = nxt[p]) b[++k] = p; for(int j = 1;j <= k;++ j) sum[j] = sum[j-1] + a[b[j]].se; for(int j = m;j <= k;++ j) chmax(ans, valv(sum[j]-sum[j-m]) - vals(a[b[j]].fi-a[b[j-m+1]].fi)); lst[nxt[i]] = lst[i]; nxt[lst[i]] = nxt[i]; } printf("%lld\n", ans); }