제출 #728052

#제출 시각아이디문제언어결과실행 시간메모리
728052Username4132Bridges (APIO19_bridges)C++14
0 / 100
918 ms5416 KiB
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
using pii = pair<int, int>;
#define forn(i, n) for(int i=0; i<(int)n; ++i)
#define forsn(i, s, n) for(int i=s; i<(int)n; ++i)
#define PB push_back
#define F first
#define S second

struct query{
    int ind, ve, weight;
    query(int Ind, int Ve, int Weight) : ind(Ind), ve(Ve), weight(Weight){}
    query(){}
};

struct reversibleChange{
    int ind, sind, par, sz;
    reversibleChange(int Ind, int Sind, int Par, int Sz) : ind(Ind), sind(Sind), par(Par), sz(Sz){};
};

const int MAXN=50010, MAXE=100010;
int n, m, q, lastLeft[MAXE], lastFull[MAXE], lastSeen[MAXE], lastWeight[MAXE], par[MAXN], size[MAXN];
bool seen[MAXE], notodo[MAXE];
pii edges[MAXE];
vector<query> upd, ask, done;
vector<pii> ans;
vector<reversibleChange> changes;

auto cmp = [](query a, query b){
    return a.weight>b.weight;
};


int root(int a){
    while(par[a]!=a) a=par[a];
    return a;
}

void combine(int edgeInd, bool save){
    int a=edges[edgeInd].F, b=edges[edgeInd].S;
    int root_a=root(a), root_b=root(b);
    if(root_a==root_b) return;
    if(size[root_a]<size[root_b]) swap(root_a, root_b);

    if(!save) changes.PB(reversibleChange(root_a, root_b, par[root_b], size[root_a]));
    size[root_a]+=size[root_b];
    par[root_b]=root_a;
}

void rollback(){
    while(!changes.empty()){
        reversibleChange ch = changes.back();
        changes.pop_back();
        par[ch.sind]=ch.par;
        size[ch.ind]=ch.sz;
    }
}

void reset(){
    changes.clear();
    forn(i, n) par[i]=i, size[i]=1;
}


int main(){
    done.reserve(MAXE);
    scanf("%d %d", &n , &m);
    forn(i, m){
        int a, b, c; scanf("%d %d %d", &a, &b, &c); --a, --b;
        edges[i]={a, b};
        done.PB(query(i, i, c));
        lastWeight[i]=c;
    }
    sort(done.begin(), done.end(), cmp);
    scanf("%d", &q);
    forn(i, q){
        int a, b, c; scanf("%d %d %d", &a, &b, &c);
        if(a==1) upd.PB(query(i+m, b-1, c));
        else ask.PB(query(i+m, b-1, c));
    }
    int qnum=upd.size(), sq=0, answered=0;
    while((sq+1)*(sq+1)<=qnum) ++sq;
    for(int l=0; l<qnum && answered<(int)ask.size(); l+=sq){
        reset();
        int r=min(l+sq, qnum);
        int bnd=(r==qnum? 1000000 : upd[r].ind);
        int lstQ=answered, updated=0;
        forsn(i, l, r) seen[upd[i].ve]=true;
        
        while(lstQ<(int)ask.size() && ask[lstQ].ind<bnd) ++lstQ;
        sort(ask.begin()+answered, ask.begin()+lstQ, cmp);
        forsn(i, answered, lstQ){
            query question = ask[i];
            while(updated<(int)done.size() && done[updated].weight>=question.weight){
                if(!seen[done[updated].ve]) combine(done[updated].ve, true);
                updated++;
            }

            forsn(j, l, r){
                if(upd[j].ind>question.ind) break;
                lastSeen[upd[j].ve]=j;
                notodo[upd[j].ve]=true;
            }
            forsn(j, l, r){
                if(lastSeen[upd[j].ve]==j && upd[j].weight>=question.weight) combine(upd[j].ve, false);
                else if(!notodo[upd[j].ve] && (lastWeight[upd[j].ve]>=question.weight)) combine(upd[j].ve, false);
            }

            int ret = size[root(question.ve)];
            ans.PB({question.ind, ret});
            forsn(j, l, r) notodo[upd[j].ve]=false;
            rollback();
        }
        answered=lstQ;
        vector<query> le, ri;
        forn(i, done.size()) if(!seen[done[i].ve]) le.PB(done[i]);
        forsn(i, l, r) if(lastSeen[upd[i].ve]==i) ri.PB(upd[i]), lastWeight[upd[i].ve]=upd[i].weight;
        sort(ri.begin(), ri.end(), cmp);
        done.resize(le.size()+ri.size());
        merge(le.begin(), le.end(), ri.begin(), ri.end(), done.begin(), cmp);
        forsn(i, l, r) seen[upd[i].ve]=false;
    }

    sort(ans.begin(), ans.end());
    for(auto pr:ans) printf("%d\n", pr.S);
}

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

bridges.cpp: In function 'int main()':
bridges.cpp:69:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   69 |     scanf("%d %d", &n , &m);
      |     ~~~~~^~~~~~~~~~~~~~~~~~
bridges.cpp:71:27: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   71 |         int a, b, c; scanf("%d %d %d", &a, &b, &c); --a, --b;
      |                      ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
bridges.cpp:77:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   77 |     scanf("%d", &q);
      |     ~~~~~^~~~~~~~~~
bridges.cpp:79:27: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   79 |         int a, b, c; scanf("%d %d %d", &a, &b, &c);
      |                      ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
#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...