E - Connected Components
首先将式子变形 易得到
a
i
−
i
≤
a
j
−
j
a_i-i\leq{a_j-j}
ai−i≤aj−j
i
−
b
i
≤
j
−
b
j
i-b_i\leq{j-b_j}
i−bi≤j−bj
按
a
i
−
i
a_i-i
ai−i由小到大来排序
a
i
−
i
a_i-i
ai−i相同则按
i
−
b
i
i-b_i
i−bi由小到大排序
然后用单调栈来维护 最上边的点始终保持最小 假如有
i
−
b
i
≤
i-b_i\leq
i−bi≤ 栈顶 那么就在保留栈顶的情况下降
≤
\leq
≤他的全部出栈 并且再将最小的那个栈顶保留 即这些点合并在了一起 加如
i
−
b
i
i-b_i
i−bi更小一筹 那么直接将其入栈作为栈顶 即无法合并 最后栈的
s
i
z
e
size
size即为连通块个数
code:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N = 1e6 + 7;
struct node{
int a;
int b;
int idx;
bool operator <(const node &sb){
if(a - idx == sb.a - sb.idx) return idx - b < sb.idx - sb.b;
return a - idx < sb.a - sb.idx;
}
};
node p[N];
int n;
void solve(){
cin >> n;
for(int i = 0;i < n;i ++){
cin >> p[i].a >> p[i].b;
p[i].idx = i;
}
sort(p,p + n);
stack<int> s;
for(int i = 0;i < n;i ++){
int t = -1e18;
int flag = 0;
if(s.size()) t = s.top();
while(!s.empty() && s.top() <= p[i].idx - p[i].b){
flag = 1;
s.pop();
}
if(flag) s.push(t);
else s.push(p[i].idx - p[i].b);
}
cout << s.size() << endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int _; _ = 1;
while(_ --){
solve();
}
return 0;
}
G - Platform Game
将同一层且 r i = l j r_i=l_j ri=lj合并成一个平台 然后直接模拟即可
code:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N = 2e5 + 7;
struct node{
int l;
int r;
int idx;
bool operator <(const node &sb){
if(idx == sb.idx) return l < sb.l;
return idx > sb.idx;
}
};
node p[N];
int n;
void solve(){
cin >> n;
for(int i = 0;i < n;i ++){
cin >> p[i].l >> p[i].r >> p[i].idx;
}
sort(p,p + n);
vector<pair<int,int>> g;
int x,y; cin >> x >> y;
for(int i = 0;i < n;i ++){
if(y < p[i].idx) continue;
if(!i) g.push_back({p[i].l,p[i].r});
else{
if(p[i].idx != p[i - 1].idx) g.push_back({p[i].l,p[i].r});
else{
if(p[i].l == p[i - 1].r){
int l = p[i - 1].l;
int r = p[i].r;
g.pop_back();
g.push_back({l,r});
} else{
g.push_back({p[i].l,p[i].r});
}
}
}
}
for(int i = 0;i < g.size();i ++){
if(x > g[i].first && x < g[i].second){
x = g[i].second;
}
}
cout << x << endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int _; cin >> _;
while(_ --){
solve();
}
return 0;
}
I - The Easiest 问题
一二三四五上山打老虎
铁签题
直接数一下就行
code:
21
L - Recharge
k 为奇数时乱搞一下 确保 x 别浪费即可
code:
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
void solve(){
int k,x,y; cin >> k >> x >> y;
int ans = 0;
if(k == 1){
ans = x + y;
} else if(k & 1){
int cnt1 = k / 2;
int cnt2 = y / cnt1;
ans += min(cnt2,x);
int cnt = min(cnt2,x);
y -= min(cnt2,x) * cnt1;
x -= cnt;
if(x && (int)(y * 2 + x) >= k) ans ++,x -= (k - y * 2);
ans += x / k;
ans += y * 2 / (k + 1);
} else{
ans += (x + y * 2) / k;
}
cout << ans << endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr),cout.tie(nullptr);
int _; cin >> _;
while(_ --){
solve();
}
return 0;
}