Submission #1113073

#TimeUsernameProblemLanguageResultExecution timeMemory
1113073RequiemBridges (APIO19_bridges)C++17
59 / 100
3059 ms56596 KiB
#include<bits/stdc++.h>
//#define int long long
#define pb push_back
#define fast ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
#define MOD 1000000007
#define inf 1e18
#define fi first
#define se second
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FORD(i,a,b) for(int i=a;i>=b;i--)
#define sz(a) ((int)(a).size())
#define endl '\n'
#define pi 3.14159265359
#define TASKNAME "bridges"
using namespace std;
template<typename T> bool maximize(T &res, const T &val) { if (res < val){ res = val; return true; }; return false; }
template<typename T> bool minimize(T &res, const T &val) { if (res > val){ res = val; return true; }; return false; }
typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef vector<int> vi;
/**
Chia block
**/

const int MAXN = 5e5 + 9;
const int block = 256;

struct DSU{
    vector<int> par;
    vector<int> ranking;
    vector<ii> upd;
    DSU(int sz = 0){
        par.resize(sz + 1);
        ranking.resize(sz + 1);
        fill(ranking.begin(), ranking.end(), 1);
        iota(par.begin(), par.end(), 0);
    }

    int root(int u){
        if (par[u] == u) return u;
        return root(par[u]);
    }

    void unite(int u, int v){
        u = root(u);
        v = root(v);
        if (u != v){
            if (ranking[u] < ranking[v]) swap(u, v);
            ranking[u] += ranking[v];
            par[v] = u;
            upd.pb(ii(u, v));
        }
    }

    void rollback(){
        int u = upd.back().fi;
        int v = upd.back().se;
        ranking[u] -= ranking[v];
        par[v] = v;
        upd.pop_back();
    }
};
struct edge{
    int u, v, w;
} edge[MAXN];



int n, m, q, answer[MAXN];
iii query[MAXN];

bool changed[MAXN]; //cho biet lieu nhung thang co bi thay doi.
vector<ii> currentQuery;
vector<int> modifyEdge;
vector<int> unchanged; //list nhung canh khong thay doi
vector<int> prepareEdge[MAXN];
main()
{
    fast;
    if (fopen(TASKNAME".inp","r")){
        freopen(TASKNAME".inp","r",stdin);
        freopen(TASKNAME".out","w",stdout);
    }

    cin >> n >> m;
    FOR(i, 1, m){
        int u, v, w;
        cin >> edge[i].u >> edge[i].v >> edge[i].w;
    }
    cin >> q;

    for(int i = 1; i <= q; i++){
        cin >> query[i].fi >> query[i].se.fi >> query[i].se.se;
    }
    memset(answer, -1, sizeof(answer));

    for(int i = 1; i <= q; i += block){
        int l = i;
        int r = i + block - 1;
        DSU D(n);

        FOR(j, l, r){
            if (query[j].fi == 1){
                changed[query[j].se.fi] = true;
                modifyEdge.pb(query[j].se.fi);
            }
            else{
                currentQuery.pb(ii(query[j].se.se, j));
            }
        }

        FOR(j, l, r){
            if (query[j].fi == 1){
                //gan trong so canh
                edge[query[j].se.fi].w = query[j].se.se;
            }
            else{
                for(auto e: modifyEdge){
                    if (edge[e].w >= query[j].se.se) prepareEdge[j].pb(e);
                }
            }
        }

        FOR(j, 1, m){
            if (changed[j] == 0) unchanged.pb(j);
            else changed[j] = 0;
        }

        sort(currentQuery.begin(), currentQuery.end());
        sort(unchanged.begin(), unchanged.end(), [&](const int &a, const int &b){
             return edge[a].w < edge[b].w;
        });

        FORD(i, (int) currentQuery.size() - 1, 0){
            while(!unchanged.empty() and edge[unchanged.back()].w >= currentQuery[i].fi){
                D.unite(edge[unchanged.back()].u, edge[unchanged.back()].v);
                unchanged.pop_back();
            }

            int old = D.upd.size();
            for(auto e: prepareEdge[currentQuery[i].se]){
                D.unite(edge[e].u, edge[e].v);
            }
            answer[currentQuery[i].se] = D.ranking[D.root(query[currentQuery[i].se].se.fi)];
            while(D.upd.size() > old) D.rollback();
        }

        unchanged.clear();
        currentQuery.clear();
        modifyEdge.clear();
    }


    FOR(i, 1, q){
        if (answer[i] != -1) cout << answer[i] << endl;
    }
}
/**
Warning:
Đọc sai đề???
Cận lmao
Code imple thiếu case nào không.
Limit.
**/

Compilation message (stderr)

bridges.cpp:77:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
   77 | main()
      | ^~~~
bridges.cpp: In function 'int main()':
bridges.cpp:87:13: warning: unused variable 'u' [-Wunused-variable]
   87 |         int u, v, w;
      |             ^
bridges.cpp:87:16: warning: unused variable 'v' [-Wunused-variable]
   87 |         int u, v, w;
      |                ^
bridges.cpp:87:19: warning: unused variable 'w' [-Wunused-variable]
   87 |         int u, v, w;
      |                   ^
bridges.cpp:145:32: warning: comparison of integer expressions of different signedness: 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  145 |             while(D.upd.size() > old) D.rollback();
      |                   ~~~~~~~~~~~~~^~~~~
bridges.cpp:81:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   81 |         freopen(TASKNAME".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
bridges.cpp:82:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   82 |         freopen(TASKNAME".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...