Submission #196965

#TimeUsernameProblemLanguageResultExecution timeMemory
196965AkashiBridges (APIO19_bridges)C++14
100 / 100
2882 ms12280 KiB
#include <bits/stdc++.h>
using namespace std;

const int N = 5e4 + 5;
const int M = 1e5 + 5;
const int bucket_size = 700;

struct edges{
    int x, y, w, p, p2;
    bool operator < (const edges &aux)const{
        if(w != aux.w) return w > aux.w;
        return p < aux.p;
    }
};

inline bool cmp(edges a, edges b){
    return a.p < b.p;
}

struct query{
    int x, w, p;
    bool operator < (const query &aux)const{
        if(w != aux.w) return w > aux.w;
        return p < aux.p;
    }
};

edges a[M], e[M], b[2 * bucket_size + 5];
query Q[M];
int n, m, q;
bool uz[M], f[M];
int SZ[N], TT[N];
int tip[M], ans[M], Last[M];
vector <int> v[N];

inline int find(int x){
    int R = x;
    while(R != TT[R]) R = TT[R];
    while(x != R){
        int aux = TT[x];
        TT[x] = R;
        x = aux;
    }
    return R;
}

inline void unite(int x, int y){
    if(x == y) return ;
    if(SZ[x] > SZ[y]) SZ[x] += SZ[y], TT[y] = x;
    else SZ[y] += SZ[x], TT[x] = y;
}

bool viz[N];
vector <int> qu;
int bfs(int nod){
    int ans = SZ[nod];
    qu.push_back(nod);
    viz[nod] = 1;

    int i = 0;
    while(i < qu.size()){
        nod = qu[i++];
        for(auto it : v[nod]){
            if(viz[it]) continue ;
            viz[it] = 1;
            ans += SZ[it];
            qu.push_back(it);
        }
    }

    for(auto it : qu) viz[it] = 0;
    qu.clear();

    return ans;
}


int main()
{
//    freopen("1.in", "r", stdin);
//    freopen("1.out", "w", stdout);

    scanf("%d%d", &n, &m);

    for(int i = 1; i <= m ; ++i){
        scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].w);
        a[i].p = i;
        e[i] = a[i];
    }

    scanf("%d", &q);
    int x, y, w;
    int i = 1;
    while(i <= q){
        memset(uz, 0, sizeof(uz));
        memset(Last, 0, sizeof(Last));
        sort(a + 1, a + m + 1);
        for(int i = 1; i <= n ; ++i) TT[i] = i, SZ[i] = 1;

        int k = 0, nr = 0;
        while(k <= bucket_size && i <= q){
            scanf("%d%d%d", &tip[i], &x, &w);
            if(tip[i] == 1){
                if(!uz[x]) b[++k] = {e[x].x, e[x].y, e[x].w, 0, i - 1};
                b[++k] = {e[x].x, e[x].y, w, i, q};

                if(Last[x]) b[Last[x]].p2 = i - 1;

                uz[x] = 1; Last[x] = k;
                e[x].w = w;
            }
            else Q[++nr] = {x, w, i};
            ++i;
        }

        sort(Q + 1, Q + nr + 1);
        sort(b + 1, b + k + 1, cmp);

        int j = 1;
        for(int i = 1; i <= nr ; ++i){
            while(j <= m && Q[i].w <= a[j].w){
                if(!uz[a[j].p]) unite(find(a[j].x), find(a[j].y));
                ++j;
            }

            for(int t = 1; t <= k ; ++t){
                if(b[t].p > Q[i].p) break ;
                if(b[t].w >= Q[i].w && (b[t].p <= Q[i].p && Q[i].p <= b[t].p2)){
                    x = find(b[t].x); y = find(b[t].y);
                    if(x != y){
                        v[x].push_back(y);
                        v[y].push_back(x);
                    }
                }
            }

            ans[Q[i].p] = bfs(find(Q[i].x));

            for(int t = 1; t <= k ; ++t){
                if(b[t].p > Q[i].p) break ;
                if(b[t].w >= Q[i].w && (b[t].p <= Q[i].p && Q[i].p <= b[t].p2)){
                    x = find(b[t].x); y = find(b[t].y);
                    if(x != y){
                        v[x].clear();
                        v[y].clear();
                    }
                }
            }
        }

        for(int i = 1; i <= m ; ++i) a[i].w = e[a[i].p].w;
    }

    for(int i = 1; i <= q ; ++i)
        if(tip[i] == 2) printf("%d\n", ans[i]);

    return 0;
}
























Compilation message (stderr)

bridges.cpp: In function 'int bfs(int)':
bridges.cpp:61:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     while(i < qu.size()){
           ~~^~~~~~~~~~~
bridges.cpp: In function 'int main()':
bridges.cpp:83:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d%d", &n, &m);
     ~~~~~^~~~~~~~~~~~~~~~
bridges.cpp:86:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].w);
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bridges.cpp:91:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &q);
     ~~~~~^~~~~~~~~~
bridges.cpp:102:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
             scanf("%d%d%d", &tip[i], &x, &w);
             ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...