QOJ.ac

QOJ

ID提交记录ID题目HackerOwner结果提交时间测评时间
#328#100595#2211. IOI Problem RevisedUnique_Hanpicharlie2005Success!2023-05-04 22:30:512023-05-04 22:30:54

详细

Extra Test:

Time Limit Exceeded
ID题目提交者结果用时内存语言文件大小提交时间测评时间
#100595#2211. IOI Problem Revisedcharlie2005TL 5775ms57420kbC++233.3kb2023-04-26 23:11:302023-05-04 22:38:39

answer

#include<bits/stdc++.h>
#define int long long
#define gmax(x,y) x=max(x,y)
#define gmin(x,y) x=min(x,y)
#define F first
#define S second
#define P pair
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i<b;i++)
#define V vector
#define RE return
#define ALL(a) a.begin(),a.end()
#define MP make_pair
#define PB emplace_back
#define PF push_front
#define FILL(a,b) memset(a,b,sizeof(a))
#define lwb lower_bound
#define upb upper_bound
#define lc (x<<1)
#define rc ((x<<1)|1)
#define sz(x) ((int)x.size())
#define pc putchar
using namespace std;
int n,k,L;
int a[400005],s[400005];
P<int,int> dp[400005],dp2[400005];
int f[400005],it[400005],len;
int lst[400005];
bool tp;
int get(int l,int r){
	int mid=(l+r)>>1;
	RE (mid-l+1)*a[mid]-(s[mid]-s[l-1])+(s[r]-s[mid])-(r-mid)*a[mid];
}
int ad;
void solve(int l1,int r1,int l2,int r2){
	if(l1>r1)RE;
	int mid=(l1+r1)>>1,tl=l2;
	P<int,int> tmi=MP(1e18,1e18);
	FOR(i,l2,min(r2,mid-1)){
		P<int,int> now=MP(dp[i].F+get(i+1,mid)+ad,dp[i].S+(tp?1:-1));
		if(now<dp[mid]){
			lst[mid]=i;dp[mid]=now;
		}
		if(now<tmi){
			tmi=now;tl=i;
		}
	}
	solve(l1,mid-1,l2,tl);
	solve(mid+1,r1,tl,r2);
}
void solve(int l,int r){
	if(l==r)RE;
	int mid=(l+r)>>1;
	solve(l,mid);
	solve(mid+1,r,l,mid);
	solve(mid+1,r);
}

void check(int mid){
	ad=mid;
	FOR(i,1,n)dp[i]=MP(1e18,1e18);
	solve(0,n);
}
int b[400005];
int mi=1e18,tl[400005],tr[400005];
V<int> v;
void solve2(int l1,int r1,int l2,int r2){
	if(l1>r1)RE;
	int mid=(l1+r1)>>1;
	FOR(i,l2,r2){
		if(it[i]>=it[mid])break;
		int now=f[i]+get(it[i]+1,it[mid]);
		if(now<f[mid]){
			lst[mid]=i;f[mid]=now;
		}
	}
	solve2(l1,mid-1,l2,lst[mid]);
	solve2(mid+1,r1,lst[mid],r2);
}
void solve2(V<int> vl,V<int> vr){
	if(vl[0]>vr[0])RE;
	int md=(vl[0]+vr[0])>>1;
	len=0;
	rep(i,0,sz(vl)){
		tl[i]=len+1;
		FOR(j,vl[i],vr[i])it[++len]=j;
		tr[i]=len;
	}
	FOR(i,1,len)f[i]=1e18;
	f[md-vl[0]+1]=0;
	rep(i,1,sz(vl)){
		solve2(tl[i],tr[i],tl[i-1],tr[i-1]);
	}
	int nowmi=1e18,at=-1;
	int s=sz(vl);
	FOR(i,vl.back(),vr.back())if(i+1<=md+n){
		int now=f[len-vr.back()+i]+get(i+1,md+n);
		if(now<nowmi){
			at=len-vr.back()+i;nowmi=now;
		}
	}
	assert(at!=-1);
	V<int> mid(s);
	for(int i=s-1;i>=0;i--){
		mid[i]=it[at];
		at=lst[at];
	}
	assert(mid[0]==md);
	if(nowmi<mi){
		mi=nowmi;
		mid.PB(md+n);v.clear();
		rep(i,0,sz(mid)-1){
			v.PB(a[(mid[i]+1+mid[i+1])>>1]%L);
		}
		mid.pop_back();
	}
//	exit(0);
	mid[0]--;
	solve2(vl,mid);
	mid[0]+=2;
	solve2(mid,vr);
}
signed main(){
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n>>k>>L;
	FOR(i,1,n)cin>>a[i],a[i+n]=a[i]+L;
	FOR(i,1,n+n)s[i]=s[i-1]+a[i];
	int l=0,r=1e18,mid,ans=0;
	while(r>=l){
		mid=(l+r)>>1;
		check(mid);
		if(-dp[n].S>=k)ans=mid,l=mid+1;else r=mid-1;
	}
	check(ans);
	FOR(i,0,n)dp2[i]=dp[i],dp2[i].S=-dp2[i].S;
	tp=1;
	check(ans);
	ad=0;
	V<int> num;
	int lst=n;
	num.PB(n);
	int hav=1;
	for(int i=n-1;i>=1;i--){
		if(dp[lst].F==dp[i].F+get(i+1,lst)+ans&&hav+dp[i].S<=k&&hav+dp2[i].S>=k){
			hav++;num.PB(i);lst=i;
		}
	}
	reverse(ALL(num));
	int t=0;
	for(auto u:num)b[++t]=u;
	V<int> v1,v2;
	FOR(i,1,t)v1.PB(b[i-1]),v2.PB(b[i]);
	solve2(v1,v2);
	cout<<mi<<'\n';
	sort(ALL(v));
	for(auto u:v)cout<<u<<' ';
	RE 0;
}