由于要依次完成任务,所以对于我们从前到后把可以取交集的取交集,不行就新开一段。
这样由于要从前到后完成任务,就是这些互不相交的交集区间要依次到达。
于是我们先根据第二个区间的位置选择第一个区间开始的起点
然后就每次根据下一个区间与这个区间的相对位置选择到达的端点就行了。
有个小细节,就是走到端点长度为奇数的情况下,不一定是走到端点,而是可能再走一格,代价一样,但是对后面的更优
#include<bits/stdc++.h>
#define maxl 1010
using namespace std;
int n,m,ans,cas,cnt;
struct seg
{
int l,r;
}a[maxl],b[maxl];
char s[maxl];
inline void prework()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].l,&a[i].r);
cnt=1;b[1]=a[1];
for(int i=2;i<=n;i++)
{
if(a[i].r<b[cnt].l || a[i].l>b[cnt].r)
b[++cnt]=a[i];
else
{
b[cnt].l=max(b[cnt].l,a[i].l);
b[cnt].r=min(b[cnt].r,a[i].r);
}
}
}
inline void mainwork()
{
int id,len;
ans=0;
if(b[2].r<b[1].l)
id=b[1].l;
else
id=b[1].r;
for(int i=2;i<=cnt;i++)
{
if(b[i].r<b[i-1].l)
{
len=id-b[i].r,id=b[i].r;
if(len&1 && b[i].l<id && i+1<=cnt && b[i+1].r<b[i].l)
{
len++;id--;
}
}
else
{
len=b[i].l-id,id=b[i].l;
if(len&1 && b[i].r>id && i+1<=cnt && b[i+1].l>b[i].r)
{
len++;id++;
}
}
ans+=len/2;
if(len&1)
ans++;
}
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}