QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#339449 | #7605. Yet Another Mex Problem | OccDreamer | WA | 2ms | 21148kb | C++14 | 6.6kb | 2024-02-27 13:01:48 | 2024-02-27 13:01:48 |
Judging History
answer
//code by Emissary
#include<bits/stdc++.h>
#define fi first
#define se second
#define vc vector
#define db double
#define ll long long
#define pb push_back
#define mk make_pair
#define PI pair<int,int>
#define err cerr << " -_- " << endl
#define debug cerr << " --------------------- " << endl
#define input(x) freopen(#x".in","r",stdin)
#define output(x) freopen(#x".out","w",stdout)
using namespace std;
//#define int long long
namespace IO{
inline int read(){
int X=0, W=0; register char ch=getchar();
while(!isdigit(ch)) W|=ch=='-', ch=getchar();
while(isdigit(ch)) X=(X<<1)+(X<<3)+(ch^48), ch=getchar();
return W?-X:X;
}
inline void write(int x){
if(x<0) x=-x, putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void sprint(int x){write(x); putchar(32);}
inline void eprint(int x){write(x); putchar(10);}
}using namespace IO;
const int MAXN = 2e5+5;
const int inf = 1e9;
int root[MAXN<<2], root2[MAXN<<2];
int lc[MAXN*50], rc[MAXN*50], node, qtot;
int n, k, a[MAXN], tot, tag[MAXN<<2], val[MAXN<<2], minn[MAXN*50], maxn[MAXN*50];
ll dp[MAXN], pre[MAXN], Res[MAXN<<2];
struct range{
int l, r, v;
inline bool friend operator < (const range &x, const range &y){
return x.r<y.r;
}
}Q[MAXN*5];
struct LCT{
ll k, b;
bool flag;
}tree[MAXN*50];
inline ll f(ll x, LCT v){return x*v.k+v.b;}
inline void ins(int &p, int l, int r, LCT x){
if(!p) p=++node;
if(!tree[p].flag) return tree[p]=x, void();
int mid=(l+r)>>1;
if(f(mid,tree[p])<f(mid,x)) swap(tree[p],x);
if(f(l,tree[p])<f(l,x)) ins(lc[p],l,mid,x);
else ins(rc[p],mid+1,r,x);
return ;
}
inline ll ask(int p, int l, int r, int pos, ll ans){
if(!p) return ans;
if(tree[p].flag) ans=max(ans,f(pos,tree[p]));
if(l==r) return ans;
int mid=(l+r)>>1;
return pos<=mid?ask(lc[p],l,mid,pos,ans):ask(rc[p],mid+1,r,pos,ans);
}
inline void ins2(int &p, int l, int r, LCT x){
if(!p) p=++node;
if(!tree[p].flag) return tree[p]=x, void();
int mid=(l+r)>>1;
if(f(pre[mid],tree[p])<f(pre[mid],x)) swap(tree[p],x);
if(f(pre[l],tree[p])<f(pre[l],x)) ins2(lc[p],l,mid,x);
else ins2(rc[p],mid+1,r,x);
return ;
}
inline ll ask2(int p, int l, int r, int pos, ll ans){
//cerr << "ask2:" << l << ' ' << r << ' ' << tree[p].k << ' ' << tree[p].b << ' ' << ans << ' ' << pos << ' ' << pre[pos] << ' ' << tree[p].flag << endl;
if(!p) return ans;
if(tree[p].flag) ans=max(ans,f(pre[pos],tree[p]));
//cerr << "ans=" << ans << endl;
if(l==r) return ans;
int mid=(l+r)>>1;
return pos<=mid?ask2(lc[p],l,mid,pos,ans):ask2(rc[p],mid+1,r,pos,ans);
}
inline void pushmax(int p, int v){
//cerr << "insert:" << p << ' ' << v << ' ' << ask(root[p],0,n,v,-1e18) << endl;
ins2(root2[p],0,n,LCT{v,Res[p]=ask(root[p],0,n,v,-1e18),1});
tag[p]=max(tag[p],v); val[p]=max(val[p],v);
return ;
}
inline void pushup(int p){
//val[p]=max(val[p<<1],val[p<<1|1]);
//ins2(root2[p],0,n,LCT{val[p<<1],ask(root[p<<1],0,n,val[p<<1],-1e18),1});
//ins2(root2[p],0,n,LCT{val[p<<1|1],ask(root[p<<1|1],0,n,val[p<<1|1],-1e18),1});
return ;
}
inline void pushdown(int p){
if(tag[p]==0) return ;
pushmax(p<<1,tag[p]);
pushmax(p<<1|1,tag[p]);
return tag[p]=0, void();
}
inline void insert(int p, int l, int r, int pos){
ins(root[p],0,n,LCT{-pre[pos],dp[pos],1});
if(l==r) return ;
int mid=(l+r)>>1; pushdown(p);
pos<=mid?insert(p<<1,l,mid,pos):insert(p<<1|1,mid+1,r,pos);
return ;
}
inline void chkmax(int p, int l, int r, int L, int R, int v){
if(L<=l && r<=R) return pushmax(p,v);
int mid=(l+r)>>1; pushdown(p);
if(L<=mid) chkmax(p<<1,l,mid,L,R,v);
if(R>mid) chkmax(p<<1|1,mid+1,r,L,R,v);
return pushup(p);
}
inline ll Ask(int p, int l, int r, int L, int R){
if(L<=l && r<=R) return Res[p];
int mid=(l+r)>>1; ll Max=-1e18;
if(L<=mid) Max=max(Max,Ask(p<<1,l,mid,L,R));
if(R>mid) Max=max(Max,Ask(p<<1|1,mid+1,r,L,R));
return Max;
}
inline void chkmax2(int p, int l, int r, int L, int R, int v){
if(R<l || L>r) return ;
ins2(root2[p],0,n,LCT{v,Ask(1,0,n,max(l,L),min(R,r)),1});
if(L<=l && r<=R) return ;
int mid=(l+r)>>1;
if(L<=mid) chkmax2(p<<1,l,mid,L,R,v);
if(R>mid) chkmax2(p<<1|1,mid+1,r,L,R,v);
return ;
}
inline ll query(int p, int l, int r, int L, int R, int id){
if(L<=l && r<=R) return ask2(root2[p],0,n,id,-1e18);
int mid=(l+r)>>1; ll res=-1e18; pushdown(p);
if(L<=mid) res=query(p<<1,l,mid,L,R,id);
if(R>mid) res=max(res,query(p<<1|1,mid+1,r,L,R,id));
return res;
}
inline void solve(){
dp[0]=0;
insert(1,0,n,0); int now=1;
//for(int i=1;i<=qtot;++i) cerr << "range:" << Q[i].l << ' ' << Q[i].r << endl;
for(int i=1;i<=n;++i){
while(now<=qtot && Q[now].r==i){
//cerr << "now=" << now << ' ' << qtot << endl;
chkmax(1,0,n,0,Q[now].l-1,Q[now].v);
chkmax2(1,0,n,0,Q[now].l-1,Q[now].v);
++now;
}
dp[i]=max(query(1,0,n,max(i-k,0),i-1,i),dp[i-1]);
insert(1,0,n,i);
//cerr << "dp:" << i << ' ' << dp[i] << endl;
}
eprint(dp[n]);
return ;
}
inline void build1(int &now, int pre, int l, int r, int pos, int v){
now=++node; lc[now]=lc[pre]; rc[now]=rc[pre]; minn[now]=minn[pre];
if(l==r) return minn[now]=v, void();
int mid=(l+r)>>1;
pos<=mid?build1(lc[now],lc[pre],l,mid,pos,v):build1(rc[now],rc[pre],mid+1,r,pos,v);
return minn[now]=min(minn[lc[now]],minn[rc[now]]), void();
}
inline int ask1(int p, int l, int r, int L, int R){
if(L>R) return -inf;
if(L<=l && r<=R) return minn[p];
int mid=(l+r)>>1; int v=inf;
if(L<=mid) v=min(v,ask1(lc[p],l,mid,L,R));
if(R>mid) v=min(v,ask1(rc[p],mid+1,r,L,R));
return v;
}
inline int ask2(int p, int l, int r, int lim){
if(minn[p]>=lim) return -1;
if(l==r) return l;
int mid=(l+r)>>1, c=0;
c=ask2(lc[p],l,mid,lim);
if(c!=-1) return c;
return ask2(rc[p],mid+1,r,lim);
}
int main(){
//freopen("21.in","r",stdin);
//freopen("seq.in","r",stdin);
//freopen("seq.out","w",stdout);
n=read(); k=read(); minn[0]=-inf;
memset(dp,-127/3,sizeof dp);
for(int i=1;i<=n;++i) a[i]=read(), pre[i]=pre[i-1]+a[i];
for(int i=1;i<=n;++i) build1(root[i],root[i-1],0,n+1,a[i],i);
for(int i=n;i>=1;--i){
if(a[i]==0){Q[++qtot]=range{i,i,1}; continue;}
int o;
o=ask1(root[i],0,n+1,0,a[i]-1);
if(o<1) continue;
Q[++qtot]=range{o,i,ask2(root[i],0,n+1,o)};
}
memset(root,0,sizeof root); tot=0;
reverse(a+1,a+1+n);
for(int i=1;i<=n;++i) build1(root[i],root[i-1],0,n+1,a[i],i);
for(int i=n;i>=1;--i){
if(a[i]==0){Q[++qtot]=range{n-i+1,n-i+1,1}; continue;}
int o;
o=ask1(root[i],0,n+1,0,a[i]-1);
if(o<1) continue;
Q[++qtot]=range{n-i+1,n-o+1,ask2(root[i],0,n+1,o)};
}
sort(Q+1,Q+1+qtot); solve();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 17048kb
input:
5 3 3 4 0 0 3
output:
10
result:
ok 1 number(s): "10"
Test #2:
score: 0
Accepted
time: 0ms
memory: 19072kb
input:
8 4 0 1 2 0 3 1 4 1
output:
26
result:
ok 1 number(s): "26"
Test #3:
score: 0
Accepted
time: 0ms
memory: 21148kb
input:
10 5 0 2 0 1 2 1 0 2 2 1
output:
33
result:
ok 1 number(s): "33"
Test #4:
score: 0
Accepted
time: 2ms
memory: 19116kb
input:
20 10 3 1 3 2 3 3 0 1 3 0 2 3 3 3 3 1 3 0 0 3
output:
160
result:
ok 1 number(s): "160"
Test #5:
score: -100
Wrong Answer
time: 0ms
memory: 16992kb
input:
30 10 14 15 10 1 14 1 8 0 12 8 6 15 1 8 9 12 15 10 11 12 7 10 10 3 3 10 8 14 13 13
output:
268
result:
wrong answer 1st numbers differ - expected: '172', found: '268'