社区讨论

只wa#16求助

P9415「NnOI R1-T4」下楼参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mj8ebs9k
此快照首次捕获于
2025/12/16 17:44
3 个月前
此快照最后确认于
2025/12/19 18:41
3 个月前
查看原帖
https://www.luogu.com.cn/record/253500377
CPP
#include<bits/stdc++.h>
#define int long long
#define pb emplace_back
#define pii pair <int, int>
#define root 1, 1, n
using namespace std;
const int N = 5e5 + 5, inf = 1e18, none = -1, K = 20, mod = 998244353;
int q, n, dp[N];
pii s[N];
vector <int> rm[N];
vector <pii> ad[N];
struct tag{
  int st;
  tag () : st(none){}
  tag (int a) : st(a){}
  inline bool operator () () const{
    return st != none;
  }
  inline tag operator * (const tag& o) const{//mul first and then st
    return {o.st};
  }
};
struct node{
  int mn;
  node () : mn(inf) {}
  node (int a) : mn(a) {}
  inline node operator + (const node& o) const{
    return {min(mn, o.mn)};
  }
  inline node operator * (const tag& o) const{
    return {o.st};
  }
};
struct Sgt{
#define mid ((l + r) >> 1)
#define ls(p) (p << 1)
#define rs(p) (p << 1 | 1)
  node s[N << 2];
  tag t[N << 2];
  inline void push_up(const int& p){
    s[p] = s[ls(p)] + s[rs(p)];
  }
  inline void apply(const int& p, const int& l, const int& r, const tag& x){
    t[p] = t[p] * x;
    s[p] = s[p] * x;
  }
  inline void push_down(const int& p, const int& l, const int& r){
    if (!t[p]()) return;
    apply(ls(p), l, mid, t[p]);
    apply(rs(p), mid + 1, r, t[p]);
    t[p] = tag();
  }
  inline void build(const int& p, const int& l, const int& r){
    if (l == r) return s[p] = node(), void();
    push_down(p, l, r);
    build(ls(p), l, mid);
    build(rs(p), mid + 1, r);
    push_up(p);
  }
  inline node query(const int& p, const int& l, const int& r, const int& L, const int& R){
    if (l >= L && r <= R) return s[p];
    push_down(p, l, r);
    if (mid + 1 > R) return query(ls(p), l, mid, L, R);
    else if (mid < L) return query(rs(p), mid + 1, r, L, R);
    else return query(ls(p), l, mid, L, R) + query(rs(p), mid + 1, r, L, R);
  }
  inline void update(const int& p, const int& l, const int& r, const int& L, const int& R, const tag& x){
    if (l >= L && r <= R) return apply(p, l, r, x), void();
    push_down(p, l, r);
    if (mid >= L) update(ls(p), l, mid, L, R, x);
    if (mid + 1 <= R) update(rs(p), mid + 1, r, L, R, x);
    push_up(p);
  }
}tree1, tree2;
signed main(){
	cin.tie(0)->sync_with_stdio(0);
  cin >> n;
  vector <pii> disc;
  for (int i = 1; i <= n; i ++){
    cin >> s[i].first >> s[i].second;
    s[i].second *= -1;
    disc.pb(s[i].second, s[i].first);
  }
  sort(disc.begin(), disc.end());
  disc.erase(unique(disc.begin(), disc.end()), disc.end());
  for (int i = 1; i <= n; i ++)
    s[i].second = disc.end() - lower_bound(disc.begin(), disc.end(), make_pair(s[i].second, s[i].first));
  sort(s + 1, s + 1 + n);
  tree1.build(root);
  tree2.build(root);
  for (int i = 1; i <= n; i ++){
    for (auto v : rm[i]) tree1.update(root, v, v, {inf});
    for (auto [v, add] : ad[i]) tree2.update(root, v, v, add);
    int h = s[i].first, v = s[i].second;
    dp[i] = min({h, tree1.query(root, v, n).mn, tree2.query(root, v, n).mn + h});
    int pos = upper_bound(s + 1, s + 1 + n, make_pair(h + dp[i] / 2, inf)) - 1 - s;
    rm[pos + 1].pb(v);
    ad[pos + 1].pb(v, (dp[i] + 1) / 2 - h);
    tree1.update(root, v, v, {dp[i]});
  }
  cout << dp[n] << endl;
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...