QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#386166 | #7605. Yet Another Mex Problem | bear0131 | RE | 0ms | 0kb | C++14 | 6.1kb | 2024-04-11 13:21:08 | 2024-04-11 13:21:10 |
answer
#include<bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (n); ++i)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef array<int, 3> ai3;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int Mod = 1e9 + 7;
inline int sign(int a){ return (a&1) ? (Mod-1) : 1; }
inline void uadd(int &a, int b){ a += b-Mod; a += (a>>31) & Mod; }
inline void usub(int &a, int b){ a -= b, a += (a>>31) & Mod; }
inline void umul(int &a, int b){ a = (int)(1ll * a * b % Mod); }
inline int add(int a, int b){ a += b-Mod; a += (a>>31) & Mod; return a; }
inline int sub(int a, int b){ a -= b, a += (a>>31) & Mod; return a; }
inline int mul(int a, int b){ a = (int)(1ll * a * b % Mod); return a; }
int qpow(int b, ll p){ int ret = 1; while(p){ if(p&1) umul(ret, b); umul(b, b), p >>= 1; } return ret; }
const int fN = 100;
int fact[fN], invfact[fN], inv[fN];
void initfact(int n){
fact[0] = 1; for(int i = 1; i <= n; ++i) fact[i] = mul(fact[i-1], i);
invfact[n] = qpow(fact[n], Mod-2); for(int i = n; i > 0; --i) invfact[i-1] = mul(invfact[i], i);
for(int i = 1; i <= n; ++i) inv[i] = mul(invfact[i], fact[i-1]);
}
int binom(int n, int m){ return (m < 0 || m > n) ? 0 : mul(fact[n], mul(invfact[m], invfact[n-m])); }
const double pi = acos(-1);
inline void chmax(int &a, int b){ (b>a) ? (a=b) : 0; }
inline void chmin(int &a, int b){ (b<a) ? (a=b) : 0; }
inline void chmax(ll &a, ll b){ (b>a) ? (a=b) : 0; }
inline void chmin(ll &a, ll b){ (b<a) ? (a=b) : 0; }
int n;
struct line{
ll k, b;
line(){ k = 0, b = -INF; }
line(ll _k, ll _b){ k = _k, b = _b; }
inline ll gety(ll x){ return k * x + b; }
};
namespace ktt{
// max(f[j] + pre[j] * (-x))
line dat[200200];
const int B = 450;
int nxt[200200], out[200200];
void rebuild(int bi){
int bl = bi * B, br = min(n, (bi+1) * B);
for(int i = br-1; i >= bl; --i){
if(nxt[i] >= br) out[i] = i;
else out[i] = out[nxt[i]];
}
}
int h[200200], sp = 0;
bool elim(int a, int b, int c){
return (__int128)(dat[b].k - dat[a].k) * (dat[c].b - dat[a].b) - (__int128)(dat[c].k - dat[a].k) * (dat[b].b - dat[a].b) >= 0;
}
void ins(int i, line l){
//cerr << "! ins " << i << " " << l.k << "x + " << l.b << endl;
nxt[i] = inf, dat[i] = l;
rebuild(i / B);
while((sp && dat[h[sp-1]].k == l.k) || (sp >= 2 && elim(h[sp-2], h[sp-1], i)))
nxt[h[--sp]] = i, rebuild(h[sp] / B);
h[sp++] = i;
//rep(j, sp) cerr << h[j] << " ";
//cerr << endl;
}
ll qry(int tl, int x){
//cerr << "! qry " << tl << " " << x << " = ";
ll ret = -INF;
//for(int i = tl; i < n; ++i) chmax(ret, dat[i].gety(x));
//cerr << ret << endl;
//return ret;
{
int lb = 0, ub = sp-2;
while(lb <= ub){
int mid = (lb+ub) >> 1;
if(h[mid] < tl || dat[h[mid+1]].gety(x) > dat[h[mid]].gety(x))
lb = mid+1;
else
ub = mid-1;
}
if(h[lb] >= tl) ret = dat[h[lb]].gety(x);
}
{
auto isup = [&](int p){
return nxt[p] != inf && dat[nxt[p]].gety(x) > dat[p].gety(x);
};
int p = tl;
while(isup(out[p])) p = nxt[out[p]];
while(isup(p)) p = nxt[p];
chmax(ret, dat[p].gety(x));
}
//cerr << ret << endl;
return ret;
}
}
ll pre[200200];
namespace lct{
// max(k * pre[j] + b)
line dat[525252];
void ins(int tl, int tr, line cur, int l, int r, int k){
//cout << "ins " << tl << " " << tr << " " << l << " " << r << " " << k << endl;
if(tl > r || l > tr) return ;
int mid = (l+r) >> 1;
if(tl <= l && r <= tr){
if(dat[k].gety(pre[mid]) < cur.gety(pre[mid])) swap(cur, dat[k]);
if(l == r) return ;
if(dat[k].gety(pre[l]) < cur.gety(pre[l])) ins(tl, tr, cur, l, mid, k+k);
if(dat[k].gety(pre[r]) < cur.gety(pre[r])) ins(tl, tr, cur, mid+1, r, k+k+1);
} else
ins(tl, tr, cur, l, mid, k+k), ins(tl, tr, cur, mid+1, r, k+k+1);
}
ll qry(int p, int l, int r, int k){
ll ret = dat[k].gety(pre[p]);
if(l < r){
int mid = (l+r) >> 1;
chmax(ret, (p <= mid) ? qry(p, l, mid, k+k) : qry(p, mid+1, r, k+k+1));
}
return ret;
}
}
int k, a[200200];
vi ps[200200];
multiset< array<int, 3> > st; // mex, left bound, start time
ll f[200200];
void ins(int fl, int fr, int tl, int tr, int v){
//cout << "------ins " << fl << " " << fr << " " << tl << " " << tr << " " << v << "--------" << endl;
for(int i = max(fl, tl - k); i <= min(fr, tr - k); ++i){
lct::ins(tl, i + k, line(v, f[i] - v * pre[i]), 0, n, 1);
}
if(tr - k < fr){
ll b = ktt::qry(max(fl, tr - k + 1), -v);
lct::ins(tl, tr, line(v, b), 0, n, 1);
}
}
int main(){
freopen("b.in", "r", stdin);
freopen("b.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> k;
rep(i, n) cin >> a[i], ps[a[i]].push_back(i);
rep(i, n) pre[i+1] = pre[i] + a[i];
{
static int cnt[200200];
int cur = 0;
rep(i, n){
++cnt[a[i]];
if(cnt[cur]){
while(cnt[cur]) ++cur;
st.insert({cur, i, 0});
}
}
st.insert({inf, n, 0});
}
memset(ktt::nxt, 0x3f, sizeof(ktt::nxt));
f[0] = 0, ktt::ins(0, line(pre[0], f[0]));
rep(i, n + 1){
//cout << "----------------" << i << "-------------------" << endl;
//for(auto p : st) cout << "{" << p[0] << ", " << p[1] << ", " << p[2] << "} ";
//cout << endl;
if(i) f[i] = max(f[i-1], lct::qry(i, 0, n, 1)), ktt::ins(i, line(pre[i], f[i]));
//cout << "f[" << i << "] = " << f[i] << "\n";
if(i < n){
auto it = st.lower_bound({a[i], 0, 0});
int nxt = (int)(lower_bound(ps[a[i]].begin(), ps[a[i]].end(), i+1) - ps[a[i]].begin());
//cout << "[" << nxt << "] = ";
nxt = (nxt == (int)ps[a[i]].size() ? n : ps[a[i]][nxt]);
//cout << nxt << endl;
int tmpl = (*it)[1];
if(tmpl < nxt){
int ok = 1;
while(ok){
int r = (*next(it))[1];
ins((*it)[2], i, (*it)[1] + 1, r, (*it)[0]);
if(nxt <= r) ok = 0;
if(nxt < r) st.insert({(*it)[0], nxt, (*it)[2]});
it = st.erase(it);
}
if(a[i]) st.insert({a[i], tmpl, i});
}
}
}
cout << f[n] << "\n";
return 0;
}
详细
Test #1:
score: 0
Dangerous Syscalls
input:
5 3 3 4 0 0 3