제출 #991317

#제출 시각아이디문제언어결과실행 시간메모리
991317sadddMin-max tree (BOI18_minmaxtree)C++17
100 / 100
239 ms91264 KiB
#include<bits/stdc++.h>
#include<fstream>
using namespace std;
//#pragma GCC optimize("O3")
#define sz(a) (int)a.size()
#define ALL(v) v.begin(), v.end()
#define ALLR(v) v.rbegin(), v.rend()
#define ll long long
#define pb push_back
#define forr(i, a, b) for(int i = a; i < b; i++)
#define dorr(i, a, b) for(int i = a; i >= b; i--)
#define ld long double
#define vt vector
#include<fstream>
#define fi first
#define se second
#define pll pair<ll, ll>
#define pii pair<int, int>
#define mpp make_pair
const ld PI = 3.14159265359, prec = 1e-9;;
//using u128 = __uint128_t;
//const int x[4] = {1, 0, -1, 0};
//const int y[4] = {0, -1, 0, 1};
const ll mod = 1e9 + 7, pr = 31;
const int mxn = 5e5 + 5, mxq = 1e5 + 5, sq = 1005, mxv = 5e4 + 1, lg = 60;
//const int base = (1 <<18);
const ll inf = 2e9 + 5, neg = -69420, inf2 = 1e14;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
// have fun!;
int n, k;
struct ST{
    int type, st[4 * mxn + 1];
    void init(int _type){
        type = _type; //0: max, 1: min 
        if(type){
            for(int i = 1; i <= 4 * n; i++)st[i] = inf;
            
        }else{
             for(int i = 1; i <= 4 * n; i++)st[i] = -1;
        }
    }
    int comb0(int a, int b){
        return(max(a, b));
    }
    int comb1(int a, int b){
        return(min(a, b));
    }
    void upd(int nd, int l, int r, int ql, int qr, int v){
        //cout << ql << " " << qr << "\n";
        if(ql > r || qr < l)return;
        if(ql <= l && qr >= r){
            if(!type)st[nd] = comb0(st[nd], v); 
            else st[nd] = comb1(st[nd], v);
            //cout << st[nd] << " ";
            return;
        }
        int mid = (l + r) >> 1;
        upd(nd << 1, l, mid, ql, qr, v); upd(nd << 1 | 1, mid + 1, r, ql, qr, v);
    }
    int get(int nd, int l, int r, int id, int v){
        if(!type)v = comb0(v, st[nd]);
        else v = comb1(v, st[nd]);
        if(l == r)return(v);
        int mid = (l + r) >> 1;
        if(id <= mid)return(get(nd << 1, l, mid, id, v));
        else return(get(nd << 1 | 1, mid + 1, r, id, v));
    }
};
int siz[mxn + 1], pa[mxn + 1], tin[mxn + 1], tt = 0, dep[mxn + 1], head[mxn + 1];
vt<int>adj[mxn + 1];
ST stmx, stmn;
void dfs(int s, int pre){
    siz[s] = 1; pa[s] = pre;
    for(auto i: adj[s]){
        if(i != pre){
            dep[i] = dep[s] + 1;
            dfs(i, s); siz[s] += siz[i];
        }
    }
}
void hld(int s, int pre, int group){
    head[s] = group; tin[s] = ++tt;
    int mx = 0, son = -1; 
    for(auto i: adj[s]){
        if(i != pre){
            if(siz[i] > mx){
                mx = siz[i]; son = i;
            }
        }
    }
    if(!mx)return;
    hld(son, s, group);
    for(auto i: adj[s]){
        if(i != pre && i != son){
            hld(i, s, i);
        }
    }
}
void upd(int u, int v, int x, bool type){
    while(head[u] != head[v]){
        if(dep[head[u]] < dep[head[v]])swap(u, v);
        if(!type)stmn.upd(1, 1, n, tin[head[u]], tin[u], x);
        else stmx.upd(1, 1, n, tin[head[u]], tin[u], x);
        u = pa[head[u]];
    }
    if(tin[u] > tin[v])swap(u, v);
    if(!type)stmn.upd(1, 1, n, tin[u] + 1, tin[v], x);
    else stmx.upd(1, 1, n, tin[u] + 1, tin[v], x);
}
struct th{
    ll u, v, cap, flow;
};
struct Dinic{
    vt<int>level, to;
    int id = 0, curr, s, t;
    vt<vt<int>>adj;
    vt<th>edge;
    void init(int st, int en, int n){
        adj.resize(n); to.resize(n); level.resize(n); s = st; t = en;
    }
    void add_edge(int u, int v, int cap){
        adj[u].pb(id); adj[v].pb(id + 1); 
        edge.pb({u, v, cap, 1LL * 0}); edge.pb({v, u, cap, 1LL * 0});
        id += 2;
    }
    bool bfs(){
        fill(level.begin(), level.end(), -1);
        fill(to.begin(), to.end(), 0);
        level[s] = 0;
        queue<int>q; q.push(s);
        
        while(!q.empty()){
            
            int nw = q.front(); q.pop(); //cout << nw << " ";
            if(nw == t)return(true);
            for(auto i: adj[nw]){
                int v = edge[i].v; 
                if(level[v] != -1 || edge[i].flow + curr - 1 >= edge[i].cap)continue;
                level[v] = level[nw] + 1;
                q.push(v);
            }
        }
        return(level[t] != -1);
    }
    int dfs(int u, ll f){
        if(u == t)return(f);
        if(!f)return(0);
        for(int &eid = to[u]; eid < adj[u].size(); eid++){
            int cr = adj[u][eid];
            if(level[edge[cr].v] != level[u] + 1)continue;
            if(edge[cr].flow == edge[cr].cap)continue;
            ll nwf = dfs(edge[cr].v, min(f, edge[cr].cap - edge[cr].flow));
            if(!nwf)continue;
            edge[cr].flow += nwf; edge[cr ^ 1].flow  -= nwf;
            return(nwf);
        }
        return(0);
    }
    int flow(){
        int res = 0;
        for(curr = 1 << 30; curr; curr >>= 1){
            
            while(bfs()){
                for(int f = dfs(s, inf); f; f = dfs(s, inf))res += f;
            }
        }
        return(res);
    }
};
Dinic d;
int lv[mxn + 1], rv[mxn + 1], idl[mxn + 1], idr[mxn + 1];
vt<pii>edge;
map<int, int>mp;
void solve(){  
    cin >> n;
    for(int i = 0; i < n - 1; i++){
        int u, v; cin >> u >> v;
        adj[u].pb(v); adj[v].pb(u); edge.pb(mpp(u, v));
    }
    dfs(1, -1); hld(1, -1, 1);
    cin >> k;
    stmx.init(0); stmn.init(1);
    for(int i = 0; i < k; i++){
        char c; cin >> c;
        int u, v, x; cin >> u >> v >> x; mp[x] = i;
        upd(u, v, x, (c == 'm'));
    }
    d.init(0, n + k + 1, n + k + 2);
    for(int i = 0; i < n - 1; i++){
        auto [u, v] = edge[i]; if(tin[u] < tin[v])swap(u, v);
        lv[i] = stmx.get(1, 1, n, tin[u], -1); rv[i] = stmn.get(1, 1, n, tin[u], inf);
        //cout << lv[i] << " " << rv[i] << "\n";
        d.add_edge(0, i + 1, 1);
        if(lv[i] != -1){
            
            idl[i] = d.id; d.add_edge(i + 1, n + mp[lv[i]] + 1, 1); 
        }if(rv[i] != inf){
            idr[i] = d.id; d.add_edge(i + 1, n + mp[rv[i]] + 1, 1);
        }
    }
    for(int i = 0; i < k; i++){
        d.add_edge(n + i + 1, n + k + 1, 1);
    }
    d.flow();
    for(int i = 0; i < n - 1; i++){
        cout << edge[i].fi << " " << edge[i].se << " "; 
        if(lv[i] == -1 && rv[i] == inf)cout << 69420 << "\n";
        else if(lv[i] != -1 && (d.edge[idl[i]].flow || rv[i] == inf))cout << lv[i] << "\n";
        else cout << rv[i] << "\n";
    }
}
signed main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    //freopen("TESTROOMS.inp", "r", stdin);
    //freopen("TESTROOMS.out", "w", stdout);
    int tt; tt = 1;
    while(tt--){
        solve();

    }
    return(0);
}

컴파일 시 표준 에러 (stderr) 메시지

minmaxtree.cpp: In member function 'int Dinic::dfs(int, long long int)':
minmaxtree.cpp:148:35: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  148 |         for(int &eid = to[u]; eid < adj[u].size(); eid++){
      |                               ~~~~^~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...