题目:点击打开链接
题意:有一盏灯,0时刻开着。n次操作,你可以在其中加入一次操作(或者不加),操作为:a[i]时刻按一下开关,状态变为相反状态(开->关or关->开)。问灯亮着的时长最长为多少?
保证a[i-1]<a[i]。
3 10
4 5 7
0~4开(时长为4-0),4~6关(时长为6-4),6~7开(时长为7-5),7~10关(时长为10-7)
我们可以在第3个时刻操作一下开关,过程变为:0~3开(时长为3-0),3~4关(时长为4-0),4~6开(时长为6-4),5~7关(时长为7-5),7~10开(时长为10-7),3+2+3=8
分析:我们加一次操作相当于把某个数字拆成两个,肯定为一开一关,我们肯定让改变的这个区间长度开灯时间尽可能长,操作之后的开灯时长为:该数字之前的总开灯时长+该数字之后的总关灯时长+本区间改变之后的开灯时长。 记录到第i次操作时亮灯时长记为b[i]。如果本区间为开灯状态且区间长度大于1,则操作后开灯时长为:b[i]+m-a[i]-(b[n+1]-b[i])-1,如果本区间本来为关灯状态且区间长度大于1,则则操作后开灯时长为:b[i]+a[i]-a[i-1]-1+m-a[i]-(b[n+1]-b[i]),所以遍历一遍维护最大值即可。另外可以不操作,此时开灯时长为b[n+1]。
题意:有一盏灯,0时刻开着。n次操作,你可以在其中加入一次操作(或者不加),操作为:a[i]时刻按一下开关,状态变为相反状态(开->关or关->开)。问灯亮着的时长最长为多少?
保证a[i-1]<a[i]。
3 10
4 5 7
0~4开(时长为4-0),4~6关(时长为6-4),6~7开(时长为7-5),7~10关(时长为10-7)
我们可以在第3个时刻操作一下开关,过程变为:0~3开(时长为3-0),3~4关(时长为4-0),4~6开(时长为6-4),5~7关(时长为7-5),7~10开(时长为10-7),3+2+3=8
分析:我们加一次操作相当于把某个数字拆成两个,肯定为一开一关,我们肯定让改变的这个区间长度开灯时间尽可能长,操作之后的开灯时长为:该数字之前的总开灯时长+该数字之后的总关灯时长+本区间改变之后的开灯时长。 记录到第i次操作时亮灯时长记为b[i]。如果本区间为开灯状态且区间长度大于1,则操作后开灯时长为:b[i]+m-a[i]-(b[n+1]-b[i])-1,如果本区间本来为关灯状态且区间长度大于1,则则操作后开灯时长为:b[i]+a[i]-a[i-1]-1+m-a[i]-(b[n+1]-b[i]),所以遍历一遍维护最大值即可。另外可以不操作,此时开灯时长为b[n+1]。
代码:
#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define MOD 1000000007
#define PI acos(-1.0)
const int N = 1e6+10;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int n,m,a[N],b[N];
int main() {
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>m;
int f=1;
for(int i=1;i<=n;i++) {
cin>>a[i];
b[i]=b[i-1]+f*(a[i]-a[i-1]);
f=1-f;
}
a[n+1]=m;
b[n+1]=b[n]+f*(m-a[n]);
int ans=b[n+1];
for(int i=1;i<=n+1;i++) {
if(a[i]-a[i-1]>1) {
if(i&1) ans=max(ans,b[i]-1+m-a[i]-(b[n+1]-b[i]));
else ans=max(ans,b[i]+a[i]-a[i-1]-1+m-a[i]-(b[n+1]-b[i]));
}
}
cout<<ans<<endl;
return 0;
}