题目大意:
遇到了我最讨厌的模拟题。
题解:
难度其实不是很大,但是B题花的时间太多了,这个又没有想的特别明白。
很容易的想到,这个可以分成两种,一个是区间相交,一个是区间不相交。
-
对于区间相交,这个很简单,首先求出n个相交的和
-
然后对于每一个求出除开相交还可以1换1的长度
-
然后求一下能不能1换1解决,不能则要2换1
-
对于区间不相交,这个稍稍复杂,可以有两种写法
-
第一种 (O(1)):首先贪心的考虑先弥合区间,然后1换1,这样肯定是更优的
-
然后对于最后一个,可能弥合区间再1换1,不如直接2换1,所以要特判一下。
-
但是只针对最后一个,假设弥合的代价是 (x) ,那么我需要换的是 (d) ,那么可以分两种情况:
- (d<len) ((len) 表示区间1换1的长度),那么只要 (2*d>d+x) 即可
- (d>len) 那么就直接弥合即可
-
第二种是暴力,直接枚举弥合的数量,其他就直接2换1。
#include <bits/stdc++.h>
#define debug(x) printf("debug:%s=%lld
",#x,x);
using namespace std;
const int maxn = 1e5+10;
typedef long long ll;
int main(){
int t;
scanf("%d",&t);
while(t--){
ll n,k;
scanf("%lld%lld",&n,&k);
ll l,r,x,y;
scanf("%lld%lld%lld%lld",&l,&r,&x,&y);
ll L = max(l,x),R = min(r,y),num = max(0ll,R-L);
ll len = max(r,y)-min(l,x)-num,cost = max(0ll,L-R);
k-=num*n;
ll ans = 0;
if(k>0){
//这个一定要有,这个主要是为了有一对已经是弥合的状态,不然后面就不能用 2换1
ans+=cost;
ans+=min(len,k);
k-=min(len,k);
}
if(k>0&&len){
//如果len==0,那么就直接2换1即可
ll cur = min(n-2,k/len);
// printf("ss
");
k -= cur*len;
ans += cur*(cost+len);
if(k>=cost){
ans+=min(k,len)+cost;
k-=min(k,len);
}
}
// printf("len=%lld cost =%lld k=%lld ans = %lld
",len,cost,k,ans);
if(k>0) ans+=2*k;
printf("%lld
",ans);
}
return 0;
}
/*
1
1 9
2 9
2 9
*/