ABC462 C-E 题解
C 题
介绍一种赛时想到的不需要数据结构的做法。
我们发现映射到图上之后,对于每一个点作为顶点时,矩形里有其他点当且仅当有至少一个点横坐标和纵坐标都小于等于这个点的。按横坐标排序之后,我们可以保证第 \(i\) 个点之前的每个点横坐标都小于等于第 \(i\) 个点,所以只需要维护前 \(i-1\) 个点的纵坐标最小值,然后判断这个最小值是否不大于第 \(i\) 个点的纵坐标。
你如何看待 AT 比赛 CF 化?
AC 代码
//#pragma GCC optimize("O3")
//#pragma GCC optimize("O2")
#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define is insert
#define fr(i,a,b) for(int i=(a);i<=(b);i++)
#define rf(i,a,b) for(int i=(a);i>=(b);i--)
#define prq priority_queue
#define gYES cout << "YES\n"
#define gNO cout << "NO\n"
#define gYes cout << "Yes\n"
#define gNo cout << "No\n"
const int MOD=998244353;
const int Mod=1e9+7;
const int N=3e5;
using namespace std;
int max(int ax,int ay){ return (ax>ay)?ax:ay; }
int min(int ax,int ay){ return (ax<ay)?ax:ay; }
int abss(int ax){ return max(ax,-ax); }
void fastIO(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0); }
int t,n;
struct point{
int x,y;
};
point a[N+5];
bool cmp1(point ax,point ay){
if(ax.x==ay.x) return (ax.y<ay.y);
return (ax.x<ay.x);
}
void solve(){
cin >> n;
fr(i,1,n){
int x,y;
cin >> x >> y;
a[i]={x,y};
}sort(a+1,a+n+1,cmp1);
int minn=a[1].y;int cnt=1;
fr(i,2,n){
if(a[i].y<minn){
cnt++;
minn=a[i].y;
}
}cout << cnt;
cout << endl; return;
}
signed main(){
fastIO();
//cin >> t;
//while(t--){
solve();
//}
return 0;
}
D 题
赛时用树状数组水过去了,但是非常不喜欢数据结构。严肃学习结论化做法。
观察到对于时间 \(l,r\),实际上作案的 \(d\) 时间内是不可选的,也就是说实际可选的作案时间是 \(l\) 到 \(r-d\)。
然后注意到作案时间是 \(10^6\) 以内的,这启示我们枚举作案开始的时间。设 \(f_i\) 是时刻 \(i\) 在房间里的候选人,那就可以组合数 \(C^2_{f_i}\),也就等同于 \(\frac{(f_i-1)\times f_i}{2}\)。
如何求 \(f_i\) 呢?其实只需要差分就可以了。一段时间映射到差分数组上,也就是 \(c_l\) 加一,\(c_{r-d+1}\) 减一。
另:赛时群里的批话
如果出现人物不想出现的可以让我删除。

AC 代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N = 1e6 + 10;
const int MOD = 998244353;
ll n, d, ans, c, f[N];
int main() {
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin >> n >> d;
for (int i = 0, s, t; i < n; i++) {
cin >> s >> t;
ll r = t - d;
if (r >= s) {
f[s]++, f[r + 1]--;
}
}
for (int x = 1; x <= 1e6; x++) {
c += f[x];
ans += c * (c - 1) / 2;
}
cout << ans;
return 0;
}
浙公网安备 33010602011771号