CF2275D Precision Alignment 题解
考虑如何区。
最小的最大显然考虑二分,二分可以达到的这个
那么 check 的时候只需要处理每个三元组和提升到
因此问题转化为只需要知道对于一组
首先如果
然后如果
否则,只要存在
如果无法直接提升就是
那么就可以据此写 check 函数了。注意二分范围一定要开足。
::::success[code && submission]
#include<bits/stdc++.h>
#define LL long long
#define UInt unsigned int
#define ULL unsigned long long
#define LD long double
#define pii pair<int,int>
#define pLL pair<LL,LL>
#define pDD pair<LD,LD>
#define fr first
#define se second
#define pb push_back
#define isr insert
#define _i128 __int128
using namespace std;
const int N = 2e5+5;
const LL INF = 2e18+1099;
LL T,n,k,a[N],b[N],c[N],l,r,Ans;
LL read(){
LL su=0,pp=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')pp=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){su=su*10+ch-'0';ch=getchar();}
return su*pp;
}
LL get__(int i,LL up){
if(a[i]+b[i]+c[i]>=up)return 0;
if(a[i]==b[i]&&b[i]==c[i])return -1;
if(a[i]>b[i]||a[i]>c[i]||b[i]>c[i])
return up-a[i]-b[i]-c[i];
return up-a[i]-b[i]-c[i]+2*min(b[i]-a[i]+1,c[i]-b[i]+1);
}
bool check(LL up){
LL cnt=0;
for(int i=1;i<=n;i++){
LL now=get__(i,up);
if(now<0)return 0;
cnt+=now;
if(cnt>k)return 0;
}
return (cnt<=k);
}
int main(){
T=read();
while(T--){
n=read(),k=read();
for(int i=1;i<=n;i++)
a[i]=read(),b[i]=read(),c[i]=read();
l=-INF,r=INF,Ans=-INF;
while(l<=r){
LL mid=(l+r)>>1;
if(check(mid))Ans=mid,l=mid+1;
else r=mid-1;
}
cout<<Ans<<"\n";
}
return 0;
}
::::
如果本篇题解对你有帮助的话,麻烦你点一个小小的赞,真是太感谢啦!