抽象出各个区间然后区间合并
区间合并算法 按左端点从小到大进行排序,并设立一个变量记录此时的最右端,从1->n扫一遍 每次分情况讨论且刷新最右端值这个比较好想
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<utility>
#include<vector>
#define LL long long
using namespace std;
LL a[110000],n,L,R;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
vector<pair<LL,LL> >ve;
scanf("%I64d%I64d%I64d",&n,&L,&R);
for(int i=0;i<n;i++)scanf("%I64d",&a[i]);
sort(a,a+n);
for(int i=n-1;i>=1;i--)
{
if(a[i]+a[i-1]-1<L||a[i]-a[i-1]+1>R)continue;
ve.push_back(make_pair(max(a[i]-a[i-1]+1,L),min(a[i]+a[i-1]-1,R)));
}
sort(ve.begin(),ve.end());//此段为区间合并
LL sum = 0;
LL maxR;
if(ve.size())
{
sum = ve[0].second - ve[0].first+1;
maxR = ve[0].second;
}
for(int i=1;i<ve.size();i++)
{
if(ve[i].first>maxR)sum += ve[i].second - ve[i].first+1,maxR = ve[i].second;
else if(ve[i].second<=maxR)continue;
else sum+=ve[i].second-maxR,maxR = ve[i].second;
}//结束记录了区间合并的长度
printf("%I64d\n",R-L+1-sum);
}
return 0;
}