QOJ.ac
QOJ
ID | 提交记录ID | 题目 | Hacker | Owner | 结果 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|
#1539 | #887977 | #2211. IOI Problem Revised | lizhous | lizhous | Failed. | 2025-02-07 21:11:22 | 2025-02-07 21:11:22 |
詳細信息
Extra Test:
Accepted
time: 1036ms
memory: 73644kb
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#887977 | #2211. IOI Problem Revised | lizhous | AC ✓ | 1004ms | 75324kb | C++14 | 5.6kb | 2025-02-07 21:09:09 | 2025-02-07 21:09:10 |
answer
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<set>
#include<queue>
#include<unordered_map>
#include<map>
#include<random>
#define int long long
using namespace std;
long long n,k,L,a[1000001],sum[1000001];
long long ans;
vector <long long> rans;
int w(int l,int r)
{
if(l==0) l=1;
if(l>r) return 0;
int mid=l+r>>1;
return a[mid]*(mid-l+1)-(sum[mid]-sum[l-1])+(sum[r]-sum[mid])-a[mid]*(r-mid);
}
struct seg
{
int l,r;
};
vector <seg> jmp,jmp2;
namespace wqs
{
struct segg
{
int i,l,r;
};
deque <segg> q;
int f[1000001],frm[2][1000001],cnt[1000001];
bool op(int a,int b,bool c)
{
if(c==0) return a>b;
return a>=b;
}
int get(int mid,bool c)
{
// cerr<<mid<<"\n";
while(!q.empty()) q.pop_front();
q.push_back({0,1,n});
for(int i=1;i<=n;i++)
{
while(!q.empty()&&q.front().r<i) q.pop_front();
f[i]=f[q.front().i]+w(q.front().i+1,i)+mid;
// cerr<<q.front().i<<" -> "<<i<<" "<<f[i]<<"\n";
if(!c) cnt[i]=cnt[q.front().i]+1;
frm[c][i]=q.front().i;
while(!q.empty()&&q.front().r<=i) q.pop_front();
while(!q.empty()&&q.back().l>i&&op(f[q.back().i]+w(q.back().i+1,q.back().l),f[i]+w(i+1,q.back().l),c))
{
q.pop_back();
}
if(q.size())
{
int l=max(i+1,q.back().l),r=q.back().r,real=r+1;
// cerr<<l<<' '<<r<<"\n";
while(l<=r)
{
int mid=l+r>>1;
if(op(f[q.back().i]+w(q.back().i+1,mid),f[i]+w(i+1,mid),c))
{
r=mid-1;
real=mid;
}
else
{
l=mid+1;
}
}
q.back().r=real-1;
if(q.back().l==real) q.pop_back();
if(real<=n) q.push_back((segg){i,real,n});
}
else
{
q.push_back((segg){i,i+1,n});
}
}
return cnt[n];
}
void mian()
{
int l=0,r=1000000000000000000,real=r;
while(l<=r)
{
int mid=l+r>>1;
if(get(mid,0)<=k)
{
r=mid-1;
real=mid;
}
else
{
l=mid+1;
}
}
get(real,0);
get(real,1);
// for(int i=1;i<=n;i++)
// {
// cerr<<frm[0][i]<<' '<<frm[1][i]<<" "<<cnt[i]<<"\n";
// }
// return ;
int ned=k,now=n,las=n;
while(ned&&now)
{
// cerr<<ned<<' '<<now<<"\n";
if(cnt[frm[1][now]]<ned)
{
// cerr<<"JER";
now=frm[1][now];
ned--;
}
else
{
for(int i=frm[0][now];i<=frm[1][now];i++)
{
if(f[i]+w(i+1,now)+real==f[now])
{
// cerr<<i<<" : "<<cnt[i]<<"\n";
if(cnt[i]==ned-1)
{
now=i;
ned--;
break;
}
}
}
}
jmp.push_back((seg){now+1,las});
las=now;
}
}
}
namespace jumper
{
int f[2][1000001],frm[2][1000001],I;
void wk(seg a,seg b) //from a to b
{
if(b.l>b.r) return;
if(b.l==b.r)
{
f[I][b.l]=4000000000000000000;
for(int i=a.l;i<=a.r;i++)
{
if(f[I^1][i]+w(i,b.l-1)<f[I][b.l])
{
f[I][b.l]=f[I^1][i]+w(i,b.l-1);
frm[I][b.l]=i;
}
}
// cerr<<frm[I][b.l]<<" -> "<<b.l<<" "<<f[I][b.l]<<"\n";
return;
}
int mid=b.l+b.r>>1;
f[I][mid]=4000000000000000000;
for(int i=a.l;i<=a.r;i++)
{
if(f[I^1][i]+w(i,mid-1)<f[I][mid])
{
f[I][mid]=f[I^1][i]+w(i,mid-1);
frm[I][mid]=i;
}
}
//cerr<<frm[I][mid]<<" -> "<<mid<<' '<<f[I][mid]<<"\n";
wk((seg){a.l,frm[I][mid]},(seg){b.l,mid-1});
wk((seg){frm[I][mid],a.r},(seg){mid+1,b.r});
}
vector <int> run(int st,vector <seg> jmp)
{
//cerr<<st<<" : \n";
//for(seg w:jmp) cerr<<w.l<<" "<<w.r<<"\n";
jmp[0]={st,st};
f[I][st]=0;
for(int i=1;i<k;i++)
{
I^=1;
wk(jmp[i-1],jmp[i]);
}
I^=1;
wk(jmp[k-1],(seg){st+n,st+n});
//cerr<<">>"<<f[I][st+n]<<"\n";
vector <int> ret;
int now=st+n,II=I;
while(now!=st)
{
// cerr<<now<<"\n";
now=frm[I][now];
ret.push_back(now);
I^=1;
//cout<<now<<" ";
}
//cout<<'\n';
reverse(ret.begin(),ret.end());
if(f[II][st+n]<ans)
{
ans=f[II][st+n];
rans.clear();
for(int i=0;i<k-1;i++)
{
rans.push_back(((ret[i]+(ret[i+1]-1))/2));
}
// //cout<<
rans.push_back(((ret[k-1]+(ret[0]+n-1))/2));
}
return ret;
}
void work(int l,int r,vector<seg> jmp) //begin pot in [l,r] jumping
{
if(l>r) return;
int mid=l+r>>1;
vector <int> pm=run(mid,jmp);
vector <seg> nex;
for(int i=0;i<k;i++)
{
nex.push_back((seg){jmp[i].l,pm[i]});
}
work(l,mid-1,nex);
nex.clear();
for(int i=0;i<k;i++)
{
nex.push_back((seg){pm[i],jmp[i].r});
}
work(mid+1,r,nex);
}
void mian()
{
int miw=0;
for(int i=0;i<k;i++)
{
if(jmp[i].r-jmp[i].l<jmp[miw].r-jmp[miw].l) miw=i;
}
for(int i=0;i<k;i++)
{
jmp2.push_back(jmp[(i+miw)%k]);
}
for(int i=1;i<k;i++)
{
if(jmp2[i].l<jmp2[i-1].l)
{
jmp2[i].l+=n;
jmp2[i].r+=n;
}
//cerr<<jmp2[i].l<<' '<<jmp2[i].r<<'\n';
}
jmp=jmp2;
work(jmp[0].l,jmp[0].r,jmp);
}
}
signed main()
{
//freopen("compete.in","r",stdin);
//freopen("compete.out","w",stdout);
// freopen("mc\\compete\\compete5.in","r",stdin);
// freopen("mc\\compete\\compete1.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n>>k>>L;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
for(int i=n+1;i<=n+n+n;i++)
{
a[i]=a[i-n]+L;
sum[i]=sum[i-1]+a[i];
}
ans=4000000000000000000;
wqs::mian();
reverse(jmp.begin(),jmp.end());
for(int i=0;i<k;i++) jmp[i].r++;
if(jmp[0].l!=1) return -1;
jumper::mian();
cout<<ans<<"\n";
int len=0;
for(int w:rans)
{
sum[++len]=a[(w%n==0?n:w%n)]%L;
}
sort(sum+1,sum+len+1);
for(int i=1;i<=len;i++)
cout<<sum[i]<<' ';
}
/*
5 2 10
0 1 2 6 9
*/