제출 #1368264

#제출 시각아이디문제언어결과실행 시간메모리
1368264ChottuF다리 (APIO19_bridges)C++20
100 / 100
1955 ms10892 KiB
#include <bits/stdc++.h>
using namespace std;

struct DSU{
    vector<int> parent, sz;
    DSU(int n){
        sz.resize(n,1);
        parent.resize(n);
        for (int i = 0; i<n; i++){
            parent[i] = i;
        }
    }
    int find(int x){
        if (x == parent[x]) return x;
        return parent[x] = find(parent[x]);
    }
    bool merge(int a, int b){
        a = find(a);
        b = find(b);
        if (a == b) return false;
        if (sz[a] < sz[b]) swap(a,b);
        sz[a] += sz[b];
        parent[b] = a;
        return true;
    }
};

const int B = 500;

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n,m;
    cin >> n >> m;
    vector<array<int,4>> all(m);
    for (int i = 0; i<m; i++){
        int u,v,d;
        cin >> u >> v >> d;
        u--;v--;
        all[i] = {d,i,u,v};
    }
    /*
    sort(all.begin(), all.end());
    int conv[m];
    for (int i = 0; i<m; i++){
        conv[all[i][1]] = i;
    }
    */
    int q;
    cin >> q;
    vector<array<int,3>> query(q);
    for (int i = 0; i<q; i++){
        int t;
        cin >> t;
        if (t==1){
            int bj,rj;
            cin >> bj >> rj;
            bj--;
            query[i] = {t,bj,rj};
        }
        else{
            int sj, wj;
            cin >> sj >> wj;
            sj--;
            query[i] = {t, sj, wj};
        }
    }
    
    vector<vector<int>> adj(n);
    vector<bool> vis(n, false);
    vector<int> tmpw(m, 0);
    vector<int> ans(q,-1);
    vector<int> inv(n, -1);
    for (int i = 0; i*B<q; i++){
        //range is i*B to MIN[ (i+1)*B-1, M-1]
        vector<array<int,4>> cpy(all);
        /*
        for (int k = 0; k<min(i*B,q); k++){
            if (query[k][0] == 2) continue;
            int idx = query[k][1];
            cpy[idx][0] = query[k][2];
            //int idx = conv[query[i][1]];
            //cpy[idx] = 
        }*/
        //vector for the updates
        /*
        vector<int> ok(n, 0);
        vector<int> chg(n, 0);
        for (int k = i*B; k<min((i+1)*B,q); k++){
            if (query[k][0] == 2) continue;
            int idx = query[k][1];
            ok[idx] = k;
            chg[idx] = query[k][2];
        }
        vector<array<int,5>> lft; //time, w, u, v
        for (int k = 0; k<m; k++){
            auto [w, idx, u, v] = cpy[k];
            if (ok[k] == 0){
                nxt.push_back({w, u, v});
            }
            else{
                lft.push_back({ok[k],w,chg[idx],u,v});
            }
        }*/
        
        vector<array<int,3>> nxt; //w, u, v
        vector<bool> mod(m, false);
        vector<int> medges;
        for (int k = i*B; k<min((i+1)*B, q); k++){
            if (query[k][0] == 1){
                int idx = query[k][1];
                if (!mod[idx]){
                    mod[idx] = true;
                    medges.push_back(idx);
                }
            }
        }
        
        for (int k = 0; k<m; k++){
            if (!mod[k]){
                auto [w, idx, u, v] = cpy[k];
                nxt.push_back({w,u,v});
            }
        }
        
        sort(nxt.begin(), nxt.end());
        reverse(nxt.begin(), nxt.end());
        DSU dsu(n);
        int ptr = 0; int sz = nxt.size();
        vector<pair<int,int>> proc;
        for (int k = i*B; k<min((i+1)*B,q); k++){
            if (query[k][0] == 1) continue;
            proc.push_back({query[k][2], k});
            /*
            int w = query[k][2];
            while (ptr < sz && nxt[ptr][0] >= w){
                
            }*/
            
        }
        sort(proc.begin(), proc.end());
        reverse(proc.begin(), proc.end());
        for (auto u : proc){
            auto [w, t] = u;
            while (ptr < sz && nxt[ptr][0] >= w){
                auto [ww, u, v] = nxt[ptr];
                dsu.merge(u,v);
                ptr++;
            }
            vector<int> tch;
            /*
            for (auto x : lft){
                auto [tm, bj, rj, uu, vv] = x;
                int qqq = dsu.find(uu);
                int www = dsu.find(vv);
                if (t >= tm){
                    //we have to use rj
                    if (rj >= w && (qqq != www)){
                        //s.insert(dsu.find(uu));
                        //s.insert(dsu.find(vv));
                        adj[qqq].push_back(www);
                        adj[www].push_back(qqq);
                        tch.push_back(qqq);
                        tch.push_back(www);
                    }
                }
                else{
                    if (bj >= w && (qqq != www)){
                        //s.insert(dsu.find(uu));
                        //s.insert(dsu.find(vv));
                        adj[qqq].push_back(www);
                        adj[www].push_back(qqq);
                        tch.push_back(qqq);
                        tch.push_back(www);
                    }
                }
            }
            */
            
            for (int idx : medges){
                tmpw[idx] = cpy[idx][0];
            }
            for (int k = i*B; k<t; k++){
                if (query[k][0] == 1){
                    tmpw[query[k][1]] = query[k][2];
                }
            }
            
            for (int idx : medges){
                if (tmpw[idx] >= w){
                    int qqq = dsu.find(cpy[idx][2]);
                    int www = dsu.find(cpy[idx][3]);
                    
                    if (qqq != www){
                        adj[qqq].push_back(www);
                        adj[www].push_back(qqq);
                        tch.push_back(qqq);
                        tch.push_back(www);
                    }
                }
            }
            
            int stt = dsu.find(query[t][1]);
            tch.push_back(stt);
            int tot = 0;
            queue<int> qu;
            vis[stt] = true;
            qu.push(stt);
            while (!qu.empty()){
                int node = qu.front();
                qu.pop();
                
                tot += dsu.sz[node];
                for (auto rr : adj[node]){
                    if (!vis[rr]){
                        qu.push(rr);
                        vis[rr] = true;
                    }
                }
            }
            ans[t] = tot;
            for (auto aa : tch){
                adj[aa].clear();
                vis[aa] = false;
            }
        }
        for (int k = i*B; k<min((i+1)*B, q); k++){
            if (query[k][0] == 1){
                all[query[k][1]][0] = query[k][2];
            }
        }
    }
    for (int i = 0; i<q; i++){
        if (ans[i] != -1) cout << ans[i] << " ";
    }
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…