原题链接
来源:CF1000B
看的题解,一开始以为等价转化为使其中的一个时间点失效,后来发现该思路不对。
最后总结一下大体思路:
在 ai 和 ai+1 两个时刻之间加入一次操作,那么实际上不会影响 a0 到 ai 之间的亮灯情况
我们加入了一个翻转时间点之后,ai+1后面所有的灭灯时间长度和亮灯的时间长度互相交换。我们创建两个数组分别记录改变前的亮灯时间和灭灯时间,然后利用前缀和来计算所需时间,在中间的 ai 和ai+1 区间中,争取加了改变点之后,让亮灯时间变得最大,所以亮灯时间为 ai+1 - ai -1 灭灯时间为 1 .
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
int a[maxn];
int light[maxn],dark[maxn];//s1是奇数号区间
int main()
{
int t;
cin>>t;
while(t--)
{
int n,m;
cin>>n>>m;
for(int i=1; i<=n; i++)
cin>>a[i];
a[n+1]=m;
light[0]=dark[0]=0;
for(int i = 1;i<=n+1;i++) {
light[i] = light[i-1];
dark[i] = dark[i-1];
if(i&1) light[i] += a[i]-a[i-1];
else dark[i] +=a[i]-a[i-1];
}
int ans=light[n+1];//初始值
for(int i=0;i<n;i++)
{
ans=max(ans,light[i]-light[0]+dark[n+1]-dark[i+1]+a[i+1]-a[i]-1);
}
cout<<ans<<endl;
}
return 0;
}