Codeforces Round 904 (Div. 2)
https://codeforces.com/contest/1884
A.
没想到是暴力,做的很晚
B.
手玩一下即可
C. Medium Design
给定一个长为 \(n\) 的数组 \(a\) ,和若干条线段 \([l_i,r_i]\) ,你可以选择这其中的任何若干条线段,并让 \(a_l\sim a_r\) 均 \(+1\).请你计算可以得到的 \(\max(a)-\min(a)\) .
\(Solution\)
这题本来想的是先把所有的加进去,得到最大值后删去不包含最大值的线段,但是可能有多个最大值,这就很难搞了.
我们找 \(1\sim m\) 中任意一点 \(x\) ,假如这个点是要求的最大值的点,那么删去其他不包含该点的点不影响结果,所以我们可以只考虑包含了这个点的线段,一定有 \(a_i\geq a_1 ,i\in [1,x]\) , 并有 \(a_i\geq a_m ,i\in [x+1,m]\) ,那么答案一定是 \(\max(a_x-a_1,a_x-a_m)\) ,但是注意,这时候的 \(a_1,a_m\) 显然是删去了我们前面说的那些不必要的边后的 \(a_1,a_m\) ,如果对每一个 \(x\) 我们都判断一遍线段,刨除不包含 \(a_x\) 的线段,那会使得时间复杂度达到 \(O(n^2)\) ,这是显然不可行的.
可以提前把所有的 \(a_1,a_m\) 上的边删掉,删掉了包含 \(a_1\) 且不包含 \(a_x\) 的边,同时包含 \(a_1\) 和 \(a_x\) 的边被删掉,\(a_1,和a_x\) 同时减小,并不会影响答案.此时最小值变成了 \(0\) ,答案就是 \(\max(a_i)\) .注意 \(a_1\) 和 \(a_m\) 上的边应该分开删除,否则如果 \(a_1,a_m\) 都包含了 \(a_x\) 会使得答案变小了.
对于线段 \(l_i,r_i\) 的处理,采用离散化即可.
点击查看代码
#include<bits/stdc++.h>
#define l first
#define r second
using namespace std;
const int N = 1e5+10;
#define int long long
pair<int,int> p[N];
int a[2*N];
int idx = 0;
vector<int> mp; // 存储所有待离散化的值
// 二分求出x对应的离散化的值
int find(int x) // 找到第一个大于等于x的位置
{
int l = 0, r = mp.size() - 1;
while (l < r)
{
int mid = l + r >> 1;
if (mp[mid] >= x) r = mid;
else l = mid + 1;
}
return r + 1; // 映射到1, 2, ...n
}
void solve()
{
memset(a,0,sizeof a);
mp.clear();
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int l,r;
cin>>l>>r;
mp.push_back(l);
mp.push_back(r);
p[i].l = l;
p[i].r = r;
}
sort(mp.begin(), mp.end()); // 将所有值排序
mp.erase(unique(mp.begin(), mp.end()), mp.end()); // 去掉重复元素
for(int i=1;i<=n;i++)
{
if(p[i].l==1)continue;
int l = find(p[i].l),r = find(p[i].r);
a[l]+=1,a[r+1]-=1;
}
int ans_max = 0;
int t = 0;
for(int i=1;i<=mp.size()+1;i++)
{
t+=a[i];
ans_max = max(ans_max,t);
}
memset(a,0,sizeof a);
for(int i=1;i<=n;i++)
{
if(p[i].r==m)continue;
int l = find(p[i].l),r = find(p[i].r);
a[l]+=1,a[r+1]-=1;
}
int ans_max_2 = 0;
t = 0;
for(int i=1;i<=mp.size()+1;i++)
{
t+=a[i];
ans_max_2 = max(ans_max_2,t);
}
int ans = max(ans_max,ans_max_2);
cout<<ans<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
solve();
return 0;
}