https://codeforces.com/contest/1132/problem/C
给一个长度为n的区间 q个工人
每个工人染一个区间 只用q-2个工人 最多有多少个区间被染色
可以考虑删除2个工人 能保留最多被染色的区间
n,q<=5000 O(n2)
开始1-q 枚举先删除一个区间 vis数组计数–
先标记只有1个工人染色的区间
同时统计删除1个区间后还剩几个区间被染色tot 每次清0
num[i] 前缀和表示从1-i 只染一次的区间数量
枚举除先删除的区间外其他区间 删掉l[j]->r[j]的只染1次的区间数
染色超过1次对答案无影响
tot-(num[r[j]]-num[l[j]-1]) 取最大值
最后还原vis数组数量++
int n,q,cnt0,cnt1,cnt,res;
int l[5005],r[5005],vis[5005],book[5005],num[5005];
int main(){
cin>>n>>q;
rep(i,1,q){
cin>>l[i]>>r[i];
for(int j=l[i];j<=r[i];j++){
vis[j]++;
}
}
for(int i=1;i<=n;i++){
if(vis[i])
cnt++;
// cout<<vis[i]<<" ";
}
// cout<<endl;
for(int i=1;i<=q;i++){
memset(num,0,sizeof num);
for(int j=l[i];j<=r[i];j++){
vis[j]--;
}
int tot=0;
for(int j=1;j<=n;j++){
if(vis[j])
tot++;
if(vis[j]==1)
book[j]=1;
else
book[j]=0;
num[j]=num[j-1]+book[j];
}
// cout<<tot<<endl;
// for(int j=1;j<=n;j++)
// cout<<num[j]<<" ";
// cout<<endl;
for(int j=1;j<=q;j++){
if(i==j)
continue;
// cout<<"第"<<j<<" : "<<tot-(num[r[j]]-num[l[j]-1])<<endl;
res=max(res,tot-(num[r[j]]-num[l[j]-1]));
}
for(int j=l[i];j<=r[i];j++)
vis[j]++;
}
cout<<res<<endl;
return 0;
}