题解 CF903G【Yet Another Maxflow Problem】

加边 An0An+1B00B1。称形如 AiAi+1 的边为左部边,形如 BjBj+1 的边为右部边,形如 AiBj 的边为中间边。

根据最大流最小割定理,将最大流问题转化为最小割问题求解。显然,至少存在一组最小割,包含恰好一条左部边、恰好一条右部边和若干条中间边。

设割了左部边 AiAi+1、右部边 BjBj+1,则割掉的中间边一定是 AuBv,其中 uiv>j。设此时割掉的所有中间边的容量和为 ci,j,则答案为 mini{ai+minj{bj+ci,j}}。设 pi=minj{bj+ci,j},答案即为 mini{ai+pi}

初始时 pi 可通过扫描线求出,由于修改操作是对 ai 的单点改,再使用线段树维护单点改、区间 min 即可。

//By: OIer rui_er
#include <bits/stdc++.h>
#define rep(x, y, z) for(ll x = (y); x <= (z); ++x)
#define per(x, y, z) for(ll x = (y); x >= (z); --x)
#define debug(format...) fprintf(stderr, format)
#define fileIO(s) do {freopen(s".in", "r", stdin); freopen(s".out", "w", stdout);} while(false)
#define endl '\n'
using namespace std;
typedef long long ll;

mt19937 rnd(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
ll randint(ll L, ll R) {
    uniform_int_distribution<ll> dist(L, R);
    return dist(rnd);
}

template<typename T> void chkmin(T& x, T y) {if(x > y) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}

const ll N = 2e5 + 5;

ll n, m, q, a[N], b[N], p[N];
vector<tuple<ll, ll>> e[N];

struct SegmentTree {
    ll val[N << 2], tag[N << 2];
    #define lc(u) (u << 1)
    #define rc(u) (u << 1 | 1)
    void pushup(ll u) {
        val[u] = min(val[lc(u)], val[rc(u)]);
    }
    void pushdown(ll u) {
        if(!tag[u]) return;
        tag[lc(u)] += tag[u];
        val[lc(u)] += tag[u];
        tag[rc(u)] += tag[u];
        val[rc(u)] += tag[u];
        tag[u] = 0;
    }
    void build(ll* a, ll u, ll l, ll r) {
        tag[u] = 0;
        if(l == r) {
            val[u] = a[l];
            return;
        }
        ll mid = (l + r) >> 1;
        build(a, lc(u), l, mid);
        build(a, rc(u), mid + 1, r);
        pushup(u);
    }
    void modify(ll u, ll l, ll r, ll ql, ll qr, ll k) {
        if(ql <= l && r <= qr) {
            tag[u] += k;
            val[u] += k;
            return;
        }
        pushdown(u);
        ll mid = (l + r) >> 1;
        if(ql <= mid) modify(lc(u), l, mid, ql, qr, k);
        if(qr > mid) modify(rc(u), mid + 1, r, ql, qr, k);
        pushup(u);
    }
    void clear(ll u, ll l, ll r) {
        tag[u] = val[u] = 0;
        if(l == r) return;
        ll mid = (l + r) >> 1;
        clear(lc(u), l, mid);
        clear(rc(u), mid + 1, r);
    }
    #undef lc
    #undef rc
}sgt;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n >> m >> q;
    rep(u, 1, n - 1) cin >> a[u] >> b[u + 1];
    rep(i, 1, m) {
        ll u, v, w;
        cin >> u >> v >> w;
        e[u].emplace_back(v + 1, w);
    }
    sgt.build(b, 1, 1, n);
    rep(u, 1, n) {
        for(auto [v, w] : e[u]) {
            sgt.modify(1, 1, n, 1, v - 1, w);
        }
        p[u] = a[u] + sgt.val[1];
    }
    sgt.build(p, 1, 1, n);
    cout << sgt.val[1] << endl;
    while(q--) {
        ll u, w;
        cin >> u >> w;
        sgt.modify(1, 1, n, u, u, -a[u]);
        a[u] = w;
        sgt.modify(1, 1, n, u, u, +a[u]);
        cout << sgt.val[1] << endl;
    }
    return 0;
}
posted @   rui_er  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示