P14191 [ICPC 2024 Hangzhou R] Elevator II

题目给的形式化题面直接提示了最小化 \(\max\{l_{a_i}-r_{a_{i-1}},0\}\)

如果没有 \(f\) 很显然直接按 \(r\) 降序排序后代价即为 0。

思考一下, 加入 \(f\) 意味着多了 \(\max\{l_{a_1}-f\}\) 这一项的代价,就是 \(l_{a_1}\)\(f\) 的距离。

假设 \(f<l_{a_1}\),反之这一项代价为 0,不用管。在后缀提若干个 \([l,r]\)\(a_0,a_1\) 之间,显然不会对后缀代价产生影响(始终为 0),相当于有一个人从 \(f\) 出发,想走到 \(l_{a_1}\),每走 1 单位长度有 1 代价,有若干区间可以从 \(l\) 花费 0 代价到 \(r\)。于是就是典题,假设人当前在 \(p\),找到 \(r\ge p\)\(l\) 最小的区间提到前面即可。

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define fin(x) freopen(#x".in","r",stdin)
#define fout(x) freopen(#x".out","w",stdout)
#define fr(x) fin(x),fout(x);
#define Fr(x,y) fin(x),fout(y)
#define INPUT(_1,_2,FILE,...) FILE
#define IO(...) INPUT(__VA_ARGS__,Fr,fr)(__VA_ARGS__)
using namespace std;
using namespace __gnu_pbds;
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cfast ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define ll long long
#define ull unsigned long long
#define intz(x,y) memset((x),(y),sizeof((x)))
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
#define tup(x) array<int,(x)>
inline ll read(){
    ll x=0,f=1;char ch=nc();
    while(ch<48||ch>57){if(ch=='-')f=-1;ch=nc();}
    while(ch>=48&&ch<=57)x=x*10+ch-48,ch=nc();
   	return x*f;
}
//void write(int x){cout<<x<<' ';}
//void write(pii x){cout<<"P("<<x.fi<<','<<x.se<<")\n";}
//void write(vector<auto>x){for(auto i:x)write(i);cout<<'\n';}
//void write(auto *a,int l,int r){for(int i=l;i<=r;i++)write(a[i]);cout<<'\n';}
inline ll lowbit(ll x){return x&-x;}
inline int pcount(ll x){
	for(int i=0,res=0;;res+=(x>>i)&1,i++)
		if(i>60)return res;
}

//struct mt{
//	ll v;
//	mt(){v=0;}
//	mt(int x){this->v=x;}
//	inline mt operator+(mt x){return {(v+x.v)%mod};}
//	inline mt operator-(mt x){return {(v+mod-x.v)%mod};}
//	inline mt operator*(mt x){return {1ll*v*x.v%mod};}
//};
//inline void add(mt &x,mt y){x=x+y;}
//mt qp(mt x,int y){mt res(1);for(;y;x=x*x,y>>=1)if(y&1)res=res*x;return res;}
const int N=3e5+5;
#define int ll
struct P{int l,r,id;}a[N];
int f[N][20],id[N][20],n,F;
int get(int l,int r){
	int len=__lg(r-l+1);
	return (f[l][len]<f[r-(1<<len)+1][len]?id[l][len]:id[r-(1<<len)+1][len]);
}
bool vis[N];vector<int>A,q;
ll work(int beg){
	intz(vis,0),vis[beg]=1;q.clear();
	int t=beg;ll s=max(a[beg].l-F,0ll),ans=1e15;
	while(1){q.pb(a[t].id);
		ans=min(ans,s+max(a[n].l-a[t].r,0ll));
		if(t==n)break;int nxt=get(t+1,n);
		s+=max(a[nxt].l-a[t].r,0ll),t=nxt;
	}return ans;
}
inline void UesugiErii(){
	ll ans=1e15;cin>>n>>F;A.clear();
	for(int i=1,_l,_r;i<=n;i++)
		cin>>a[i].l>>a[i].r,a[i].id=i;
	sort(a+1,a+1+n,[](P x,P y){return x.r<y.r;});
	for(int i=1;i<=n;i++)f[i][0]=a[i].l,id[i][0]=i;
	for(int i=1;i<20;i++)
		for(int j=1;j+(1<<i)-1<=n;j++){
			if(f[j][i-1]<f[j+(1<<i-1)][i-1])
				f[j][i]=f[j][i-1],id[j][i]=id[j][i-1];
			else f[j][i]=f[j+(1<<i-1)][i-1],id[j][i]=id[j+(1<<i-1)][i-1];
		}
	int mn=2e9,id=0,tmp;
	for(int i=1;i<=n;i++)
		if(a[i].r>=F&&a[i].l<mn)id=i,mn=a[i].l;
	if(!id)id=n;
	if(id){
		tmp=work(id);
		if(tmp<ans)ans=tmp,swap(A,q);
	}
	for(int i=1;i<=n;i++)ans+=a[i].r-a[i].l;
	cout<<ans<<'\n';intz(vis,0);
	for(int i:A)cout<<i<<' ',vis[i]=1;
	for(int i=n;i;i--)if(!vis[a[i].id])cout<<a[i].id<<' ';cout<<'\n';
		
}
signed main(){
	cfast;
	int _=1;cin>>_;
//	cout<<_<<'\n';
	for(;_;_--)UesugiErii();
	return 0;
}
posted @ 2025-11-27 16:13  Uesugi1  阅读(1)  评论(0)    收藏  举报