C. Painting the Fence
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You have a long fence which consists of nn sections. Unfortunately, it is not painted, so you decided to hire qq painters to paint it. ii-th painter will paint all sections xx such that li≤x≤rili≤x≤ri.
Unfortunately, you are on a tight budget, so you may hire only q−2q−2 painters. Obviously, only painters you hire will do their work.
You want to maximize the number of painted sections if you choose q−2q−2 painters optimally. A section is considered painted if at least one painter paints it.
Input
The first line contains two integers nn and qq (3≤n,q≤50003≤n,q≤5000) — the number of sections and the number of painters availible for hire, respectively.
Then qq lines follow, each describing one of the painters: ii-th line contains two integers lili and riri (1≤li≤ri≤n1≤li≤ri≤n).
Output
Print one integer — maximum number of painted sections if you hire q−2q−2 painters.
Examples
input
Copy
7 5 1 4 4 5 5 6 6 7 3 5
output
Copy
7
input
Copy
4 3 1 1 2 2 3 4
output
Copy
2
input
Copy
4 4 1 1 2 2 2 3 3 4
output
Copy
3
题意:给Q个线段,要去掉两条,剩下的线段覆盖总长度最长。
思路:Q的范围允许O(n*n)复杂度,先预处理每个格子被覆盖非0次,被覆盖1次,被覆盖2次的情况,再暴力枚举去掉哪两条就ok,假如去掉X和Y两条,那么覆盖数量减少为XY部分的覆盖2次的格子数加上X xor Y部分的覆盖1次的格子数,这些通过前缀和方便求出来。
# include <bits/stdc++.h>
using namespace std;
const int N = 6e3;
int l[N], r[N], a[N];
int one[N], two[N];
int fun(int x, int y){
int s1 = 0, s2 = 0;
if(l[x] > l[y]) swap(x, y);
int tmp = min(l[y], r[x]);
s1 += one[tmp]-one[l[x]-1];
tmp = min(r[x], r[y]);
s2 += max(0, two[tmp]-two[l[y]-1]);
if(r[x] < r[y]) swap(x, y);
tmp = max(l[x], r[y]);
s1 += one[r[x]]-one[tmp-1];
return s1+s2;
}
int main(){
int n, q, sum = 0;
scanf("%d%d",&n,&q);
for(int i=0; i<q; ++i){
scanf("%d%d",&l[i], &r[i]);
++a[l[i]];
--a[r[i]+1];
}
for(int i=1; i<=n; ++i){
a[i] += a[i-1];
one[i] = one[i-1];
two[i] = two[i-1];
if(a[i] > 0) ++sum;
if(a[i] == 1) ++one[i];
else if(a[i] == 2) ++two[i];
}
int ans = 0;
for(int i=0; i<q; ++i){
for(int j=0; j<q; ++j){
if(i == j) continue;
int tmp = fun(i,j);
ans = max(ans, sum-tmp);
}
}
printf("%d\n",ans);
return 0;
}