QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#390668 | #7605. Yet Another Mex Problem | Harry27182 | WA | 1ms | 3764kb | C++14 | 5.0kb | 2024-04-15 19:41:18 | 2024-04-15 19:41:18 |
Judging History
answer
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct segment1
{
int tr[800005];
void change(int k,int l,int r,int x,int v)
{
if(l==r){tr[k]=v;return;}
int mid=(l+r)>>1;
if(x<=mid)change(k<<1,l,mid,x,v);
else change(k<<1|1,mid+1,r,x,v);
tr[k]=min(tr[k<<1],tr[k<<1|1]);
}
int query(int k,int l,int r,int x,int y)
{
if(x>y)return 0x3f3f3f3f;
if(x<=l&&r<=y)return tr[k];
int mid=(l+r)>>1,res=0x3f3f3f3f;
if(x<=mid)res=min(res,query(k<<1,l,mid,x,y));
if(y>mid)res=min(res,query(k<<1|1,mid+1,r,x,y));
return res;
}
int find(int k,int l,int r,int x)
{
if(tr[k]>=x)return -1;
if(l==r)return l;
int mid=(l+r)>>1;
if(tr[k<<1]<x)return find(k<<1,l,mid,x);
else return find(k<<1|1,mid+1,r,x);
}
}sg1;
struct point{int l,r,w;};set<point>s;
bool operator <(point x,point y)
{
if(x.w!=y.w)return x.w<y.w;
return x.l<y.l;
}
struct point2{int l,r,w;};set<point2>s2;
int n,a[200005],sum[200005],k,f[200005],cnt;
bool operator <(point2 x,point2 y)
{
if(x.r!=y.r)return x.r<y.r;
return x.l<y.l;
}
struct segment2
{
struct tree{int l,r,id;}tr[6000005];
struct line
{
int k,b;
int calc(int x){return k*x+b;}
}w[1000005];
int rt[800005],tot;
void insert(int &k,int l,int r,int x)
{
if(!k){tr[k=++tot].id=x;return;}
int mid=(l+r)>>1;
if(w[x].calc(mid)>w[tr[k].id].calc(mid))swap(x,tr[k].id);
if(l==r)return;
if(w[x].calc(l)>w[tr[k].id].calc(l))insert(tr[k].l,l,mid,x);
if(w[x].calc(r)>w[tr[k].id].calc(r))insert(tr[k].r,mid+1,r,x);
}
int query(int k,int l,int r,int x)
{
if(!k)return -0x3f3f3f3f3f3f3f3f;
int res=w[tr[k].id].calc(x),mid=(l+r)>>1;
if(x<=mid)res=max(res,query(tr[k].l,l,mid,x));
else res=max(res,query(tr[k].r,mid+1,r,x));
return res;
}
void change(int k,int l,int r,int x)
{
insert(rt[k],1,n,x);
if(l==r)return;
int mid=(l+r)>>1;
if(x<=mid)change(k<<1,l,mid,x);
else change(k<<1|1,mid+1,r,x);
}
int query(int k,int l,int r,int x,int y,int w)
{
if(x<=l&&r<=y)return query(rt[k],1,n,w);
int mid=(l+r)>>1,res=-0x3f3f3f3f3f3f3f3f;
if(x<=mid)res=max(res,query(k<<1,l,mid,x,y,w));
if(y>mid)res=max(res,query(k<<1|1,mid+1,r,x,y,w));
return res;
}
}sg2;
struct segment3
{
struct tree{int l,r,id;}tr[6000005];
struct line
{
int k,b;
int calc(int x){return k*x+b;}
}w[1000005];
const int V=4e10;
int tot,rt[800005];
void insert(int &k,int l,int r,int x)
{
if(!k){tr[k=++tot].id=x;return;}
int mid=(l+r)>>1;
if(w[x].calc(mid)>w[tr[k].id].calc(mid))swap(x,tr[k].id);
if(l==r)return;
if(w[x].calc(l)>w[tr[k].id].calc(l))insert(tr[k].l,l,mid,x);
if(w[x].calc(r)>w[tr[k].id].calc(r))insert(tr[k].r,mid+1,r,x);
}
int query(int k,int l,int r,int x)
{
if(!k)return -0x3f3f3f3f3f3f3f3f;
int res=w[tr[k].id].calc(x),mid=(l+r)>>1;
if(x<=mid)res=max(res,query(tr[k].l,l,mid,x));
else res=max(res,query(tr[k].r,mid+1,r,x));
return res;
}
void change(int k,int l,int r,int x,int w)
{
insert(rt[k],1,V,w);
if(l==r)return;
int mid=(l+r)>>1;
if(x<=mid)change(k<<1,l,mid,x,w);
else change(k<<1|1,mid+1,r,x,w);
}
int query(int k,int l,int r,int x,int y,int w)
{
if(x<=l&&r<=y)return query(rt[k],1,V,w);
int mid=(l+r)>>1,res=-0x3f3f3f3f3f3f3f3f;
if(x<=mid)res=max(res,query(k<<1,l,mid,x,y,w));
if(y>mid)res=max(res,query(k<<1|1,mid+1,r,x,y,w));
return res;
}
}sg3;
signed main()
{
cin.tie(0)->sync_with_stdio(0);
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i],sum[i]=sum[i-1]+a[i];
f[0]=0;sg2.w[1]={-sum[0],f[0]};sg2.change(1,1,n,1);
for(int i=1;i<=n;i++)
{
int now=(a[i]==0?1:0);
sg1.change(1,0,n,a[i],i);
if(s.size())
{
auto it=s.lower_bound(point{0,0,a[i]});
if(it->w==a[i])
{
int l=it->l,r=it->r;s.erase(it);s2.erase(s2.find({l,r,it->w}));
while(l<=r)
{
int w=sg1.find(1,0,n,r);
int p=max(l,sg1.query(1,0,n,0,w)+1);
s.insert(point{p,r,w});s2.insert(point2{p,r,w});
sg3.w[++cnt]={w,sg2.query(1,1,n,p,r,w)};
sg3.change(1,1,n,p,cnt);
r=p-1;
}
}
}
if(!s.size())
{
s.insert(point{i,i,now});s2.insert(point2{i,i,now});
sg3.w[++cnt]={now,sg2.query(1,1,n,i,i,now)};
sg3.change(1,1,n,i,cnt);
}
else
{
auto ed=s.begin();int l=ed->l,r=ed->r,w=ed->w;
if(w==now)
{
s.erase(*ed),s.insert(point{l,i,w});
s2.erase(s2.find(point2{l,r,w}));s2.insert(point2{l,i,w});
sg3.w[++cnt]={w,sg2.query(1,1,n,l,i,w)};
sg3.change(1,1,n,l,cnt);
}
else
{
s.insert(point{i,i,now});s2.insert(point2{i,i,now});
sg3.w[++cnt]={now,sg2.query(1,1,n,i,i,now)};
sg3.change(1,1,n,i,cnt);
}
}
//cout<<i<<'\n';
f[i]=sg3.query(1,1,n,max(1ll,i-k+1),i,sum[i]);
auto it2=s2.lower_bound({0,i-k+1,0});
f[i]=max(f[i],sg2.query(1,1,n,i-k+1,it2->r,it2->w)+sum[i]*it2->w);
if(i<n)sg2.w[i+1]={-sum[i],f[i]},sg2.change(1,1,n,i+1);
//cout<<i<<'\n';
//for(auto it=s.begin();it!=s.end();it++)cout<<it->l<<' '<<it->r<<' '<<it->w<<'\n';
//cout<<i<<' '<<f[i]<<'\n';
}
cout<<f[n];
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3764kb
input:
5 3 3 4 0 0 3
output:
10
result:
ok 1 number(s): "10"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3764kb
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: 1ms
memory: 3764kb
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: 1ms
memory: 3728kb
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: 1ms
memory: 3696kb
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:
166
result:
wrong answer 1st numbers differ - expected: '172', found: '166'