CF2055E Haystacks 题解
:::::success[Hint 1] 我们考虑将此题分为两步来做,第一步是选定这些位置被删空的顺序,第二步是贪心求出操作数,那么我们考虑顺序已经被固定了怎么做。 ::::: :::::success[Hint 2] 考虑通过邻项交换法来找到顺序是什么。 :::::
对应 Hint 1:
我们考虑将此题分为两步来做,第一步是选定这些位置被删空的顺序,第二步是贪心求出操作数,那么我们考虑顺序已经被固定了怎么做。
我们考虑如果没有
- 把第一个位置清空,清出来的放到后面去。
- 然后我们把后面的位置不断清空扔到前面去。
这种情况下显然答案是
接下来加上
这个下界是可以取到的,我们被迫往后扔的时候扔到
那么固定顺序下答案为:
对应 Hint 2:
我们考虑进行邻项交换法,我们假设我们要比较
这个条件我们是不能直接扔到 sort 里跑一遍的,因为它不是一个偏序关系,那么我们考虑进行一些适当的转化。
现在这个形式比较难看,不等式两边同时减掉
首先我们观察到,当
对于
对于
然后我们考虑一下样例这个
这样我们就做完了这道题。
时间复杂度为
:::::success[code]
#include<bits/stdc++.h>
#define inl inline
#define int long long
#define lll __int128
#define fst ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define rep(i,x,y) for(int i=x;i<=(y);++i)
#define per(i,x,y) for(int i=x;i>=(y);--i)
#define rpr(i,x,y,z) for(int i=x;i<=(y);i+=z)
#define epe(i,x,y,z) for(int i=x;i>=(y);i-=z)
#define repe(i,x,y) for(i=x;i<=(y);++i)
#define endl '\n'
#define INF 9e18
#define pb push_back
#define pob pop_back
#define pf push_front
#define pof pop_front
#define fi first
#define se second
#define lcm(x,y) x/__gcd(x,y)*y
#define ull unsigned long long
#define prr make_pair
#define pii pair<int,int>
#define gt(s) getline(cin,s)
#define at(x,y) for(auto x:y)
#define ff fflush(stdout)
#define mt(x,y) memset(x,y,sizeof(x))
#define idg isdigit
#define fp(s) string ssss=s;freopen((ssss+".in").c_str(),"r",stdin);freopen((ssss+\
".out").c_str(),"w",stdout);
#define sstr stringstream
#define all(x) x.begin(),x.end()
#define mcy(a,b) memcpy(a,b,sizeof(b))
#define ui unsigned
#define si signed
#define eb emplace_back
#define pff(x) ((x)*(x))
#define eush emplace
#define double long double
#define pdi pair<double,int>
#ifdef __unix__
#define gc getchar_unlocked
#else
#define gc _getchar_nolock
#endif
#ifdef __unix__
#define pc putchar_unlocked
#else
#define pc _putchar_nolock
#endif
using namespace std;
const int N=5e5+5;
struct node{
int a,b;
inl node(){
a=b=0;
}
inl node(int a,int b):a(a),b(b){}
}a[N];
int mx[N],mx2[N],s[N];
inl void solve(){
int n,sum=0,res=0,ans=INF;
cin>>n;
rep(i,1,n) cin>>a[i].a>>a[i].b;
rep(i,1,n) sum+=a[i].a;
rep(i,1,n) res+=a[i].b-a[i].a;
sort(a+1,a+n+1,[&](node x,node y){
if((x.a-x.b)*(y.a-y.b)<=0&&(x.a!=x.b||y.a!=y.b)) return x.a-x.b<=y.a-y.b;
if(x.a<=x.b) return x.a<y.a;
return x.b>y.b;
});
mx[0]=mx2[n+1]=-INF;
rep(i,1,n) s[i]=s[i-1]+a[i].a-a[i-1].b;
rep(i,1,n) mx[i]=max(mx[i-1],s[i]);
per(i,n,1) mx2[i]=max(mx2[i+1],s[i]);
rep(i,1,n)
if(a[i].b<=res) ans=min(ans,max(mx[i-1],mx2[i+1]-a[i].a+a[i].b));
// rep(i,1,n) cout<<a[i].a<<' '<<a[i].b<<endl;
if(ans!=INF) cout<<ans+sum<<endl;
else cout<<-1<<endl;
}
si main(){
fst;
int t;
cin>>t;
while(t--) solve();
return 'T'^'0'^'m'^'l'^'e';
}
:::::