Submission #1274117

#TimeUsernameProblemLanguageResultExecution timeMemory
1274117mactoddloverReconstruction Project (JOI22_reconstruction)C++17
100 / 100
1311 ms22680 KiB
#include<bits/stdc++.h>

#define MASK(i) (1 << (i))
#define pub push_back
#define all(v) v.begin(), v.end()
#define compact(v) v.erase(unique(all(v)), end(v))
#define pii pair<int,int>
#define fi first
#define se second
#define endl "\n"
#define sz(v) (int)(v).size()
#define dbg(x) "[" #x " = " << (x) << "]"

using namespace std;

template<class T> bool minimize(T& a, T b){if(a > b) return a = b, true;return false;}
template<class T> bool maximize(T& a, T b){if(a < b) return a = b, true;return false;}

typedef long long ll;
typedef long double ld;

mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
ll rand(ll l, ll r){return uniform_int_distribution<ll>(l, r)(rng);}

const int MAX = 1e5 + 15;

int n, m, q;
int eu[MAX], ev[MAX], ew[MAX];

struct DSU{
    int n;
    vector<int> lab;

    DSU(int n) : n(n), lab(n + 15, -1) {}

    int asc(int u){
        return lab[u] < 0 ? u : lab[u] = asc(lab[u]);
    }

    bool join(int u, int v){
        u = asc(u), v = asc(v);
        if(u == v) return false;
        if(lab[u] > lab[v]) swap(u, v);
        lab[u] += lab[v];
        lab[v] = u;
        return true;
    }
};

struct node{
    int x, a, b;
    node() : x(0), a(0), b(0) {}
    node(int x, int a, int b) : x(x), a(a), b(b) {}
    bool operator < (const node& a) const{
        return x < a.x;
    }
};

vector<int> g[MAX];
int h[MAX];
bool vis[MAX];
int par[MAX];
int nxt_of[MAX];

void dfs(int u){
    vis[u] = true;
    for(int i : g[u]){
        int v = eu[i] ^ u ^ ev[i];
        if(vis[v]) continue;
        h[v] = h[u] + 1;
        par[v] = i;
        dfs(v);
    }
}

void build(){
    fill(h + 1, h + 1 + n, 0);
    fill(vis + 1, vis + 1 + n, 0);

    for(int i = 1; i <= n; i++) if(!vis[i]){
        par[i] = 0;
        dfs(i);
    }
}

void solve(){
    cin >> n >> m;

    for(int i = 1; i <= m; i++){
        cin >> eu[i] >> ev[i] >> ew[i];
    }

    vector<int> ord(m); iota(all(ord), 1);

    sort(all(ord), [&](int i, int j){
        return ew[i] < ew[j];
    });

    DSU dsu(n);
    vector<node> evt;
    fill(nxt_of + 1, nxt_of + 1 + m, -1);

    for(int id : ord){
        //cout << dbg(id) << endl;
        int u, v, w; tie(u, v, w) = {eu[id], ev[id], ew[id]};
        if(dsu.join(u, v)){
            g[u].push_back(id);
            g[v].push_back(id);
            evt.push_back(node(0, -1, +w));
            evt.push_back(node(w, +1, -w)); //get past pivot x -> erase
            evt.push_back(node(w, +1, -w)); //sub
        }
        else{
            //cout << "here\n";
            int fu, fv; tie(fu, fv) = {u, v};

            int ma = INT_MAX, idx_prev = -1;

            while(fu != fv){
                //cerr << "truoc khi xet: " << fu << " " << fv << endl;
                if(h[fu] < h[fv]) swap(fu, fv);
                //cerr << fu << " " << fv << endl;
                int i = par[fu];
                int pu = eu[i] ^ fu ^ ev[i];
                if(minimize(ma, ew[i])){
                    idx_prev = i;
                }
                fu = pu;
                //cerr << fu << " - " << fv << endl;
            }

            assert(idx_prev != -1);

            g[eu[idx_prev]].erase(find(all(g[eu[idx_prev]]), idx_prev));
            g[ev[idx_prev]].erase(find(all(g[ev[idx_prev]]), idx_prev));

            g[u].push_back(id);
            g[v].push_back(id);

            nxt_of[idx_prev] = id;
        }

        build();
    }

    //a segment [l, r] -> [l, mid] : x - p
    //                    [mid+1, r] : p - x -> cancel + sub
    for(int i = 1; i <= m; i++) if(nxt_of[i] != -1){
        int l = ew[i], r = ew[nxt_of[i]];
        int mid = (l+r) >> 1;
        evt.push_back({mid, -1, +l});
        evt.push_back({mid, -1, +r}); //cancel l, add r
        evt.push_back({r, +1, -r});
        evt.push_back({r, +1, -r}); //cancel r
    }

    sort(all(evt));

    ll a = 0, b = 0;

    cin >> q;

    int ptr = 0;

    while(q--){
        int x; cin >> x;
        while(ptr < sz(evt) && evt[ptr].x < x){
            a += evt[ptr].a;
            b += evt[ptr].b;
            ptr++;
        }
        cout << 1LL*x*a + b << endl;
    }
}

signed main(){
    ios_base::sync_with_stdio(NULL);
    cin.tie(0); cout.tie(0);

    #define task "task"

    if(fopen(task".INP", "r")){
        freopen(task".INP", "r", stdin);
        freopen(task".OUT", "w", stdout);
    }

    int t; t = 1; //cin >> t;
    while(t--) solve();
}

Compilation message (stderr)

reconstruction.cpp: In function 'int main()':
reconstruction.cpp:183:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  183 |         freopen(task".INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
reconstruction.cpp:184:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  184 |         freopen(task".OUT", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...