暴力出奇迹。
这里得思路,就是,暴力模拟就行了。
我们先假设,拿出去一个,再枚举另一个出去后,有多少区间能够被覆盖,然后不断模拟这个操作,取最大值。
其中实现上要稍微有些地方注意一下。
#include<iostream>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
typedef pair<int, int> pir;
int n, q;
struct { int l, r; }g[5500];
int book[5500];
int one[5500];
int main()
{
cin >> n >> q;
up(i, 0, q)
{
scanf("%d %d", &g[i].l, &g[i].r);
}
up(i, 0, q)
{
upd(j, g[i].l, g[i].r)
{
book[j]++;//计算区间覆盖的次数
}
}
int tot = 0;//记录一共被覆盖的点
int ans = 0;
up(i, 0, q-1)
{
tot = 0;
upd(j, g[i].l, g[i].r)/去掉第i个人
book[j]--;
upd(i, 1, n)
{
tot += book[i] > 0;//只要book有值就加一,表示区间这个点上被覆盖掉了
if (book[i] == 1) //如果是单曲间,单独计算
one[i] = 1;
else one[i] = 0;
one[i] += one[i - 1];//加上他之前的值,因为是做差分,所以无所谓前面有多大
}
up(j, i + 1, q)
{
ans = max(ans, tot - (one[g[j].r] - one[g[j].l-1]));//区间覆盖减去,单独区间的差分
}
upd(j, g[i].l, g[i].r)
book[j]++;//记得还要再加回来
}
cout << ans << endl;
return 0;
}