Educational Codeforces Round 61 (Rated for Div. 2)C题题解

暴力出奇迹。
这里得思路,就是,暴力模拟就行了。
我们先假设,拿出去一个,再枚举另一个出去后,有多少区间能够被覆盖,然后不断模拟这个操作,取最大值。
其中实现上要稍微有些地方注意一下。

#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;
}

猜你喜欢

转载自blog.csdn.net/weixin_44019404/article/details/89152041