Submission #555820

#TimeUsernameProblemLanguageResultExecution timeMemory
555820shahriarkhanBridges (APIO19_bridges)C++14
100 / 100
2474 ms9408 KiB
#include<bits/stdc++.h>
using namespace std ;

const int MX = 1e5 + 5 , block = 800 ;

struct query
{
    int type = 0 , vertice = 0 , edge = 0 , weight = 0 , idx = 0 ;
};

bool cmp(pair<int,int> &a , pair<int,int> &b)
{
    if(a.first!=b.first) return a.first > b.first ;
    return a.second > b.second ;
}

bool cmp1(query &a , query &b)
{
    if(a.weight!=b.weight) return a.weight > b.weight ;
    return a.idx < b.idx ;
}

vector<query> temp ;

vector<pair<int,int> > edges , edg ;

int ans[MX] , typ[MX] , val[MX] , vis[MX] , cur[MX] , temp_siz , n , m ;

struct dsu_rollback
{
    int u = 0 , v = 0 , siz_u = 0 , siz_v = 0 ;
};

struct dsu
{
    vector<int> par , siz ;
    stack<dsu_rollback> s ;
    void init(int n)
    {
        par = vector<int> (n+5,0) ;
        siz = vector<int> (n+5,0) ;
        for(int i = 1 ; i <= n ; ++i)
        {
            par[i] = i ;
            siz[i] = 1 ;
        }
    }
    int find_root(int a)
    {
        if(par[a]==a) return a ;
        return find_root(par[a]) ;
    }
    int union_edge(int a , int b)
    {
        int root_a = find_root(a) , root_b = find_root(b) ;
        if(root_a==root_b) return 0 ;
        if(siz[root_b]>siz[root_a]) swap(root_a,root_b) ;
        s.push({root_a,root_b,siz[root_a],siz[root_b]}) ;
        par[root_b] = root_a ;
        siz[root_a] += siz[root_b] ;
        return 1 ;
    }
    void rollback()
    {
        if(s.empty()) return ;
        dsu_rollback cur = s.top() ;
        s.pop() ;
        par[cur.u] = cur.u ;
        siz[cur.u] = cur.siz_u ;
        par[cur.v] = cur.v ;
        siz[cur.v] = cur.siz_v ;
    }
    int find_siz(int x)
    {
        return siz[find_root(x)] ;
    }
};

void process()
{
    dsu D ;
    D.init(n) ;
    vector<query> upd , out ;
    vector<int> unused ;
    unused.reserve(block) ;
    upd.reserve(block) ;
    out.reserve(block) ;
    for(query &q : temp)
    {
        if(q.type==1)
        {
            vis[q.edge] = 1 ;
            upd.emplace_back(q) ;
        }
        else out.emplace_back(q) ;
    }
    for(int i = 1 ; i <= m ; ++i)
    {
        if(vis[i]) unused.emplace_back(i) ;
    }
    sort(out.begin(),out.end(),cmp1) ;
    sort(edg.begin(),edg.end(),cmp) ;
    int cr = 0 ;
    for(query &q : out)
    {
        while((cr<m) && (edg[cr].first>=q.weight))
        {
            if(!vis[edg[cr].second]) D.union_edge(edges[edg[cr].second].first,edges[edg[cr].second].second) ;
            ++cr ;
        }
        int rollback = 0 ;
        for(query &p : upd)
        {
            if(p.idx>q.idx) break ;
            cur[p.edge] = p.weight ;
        }
        for(query &p : upd)
        {
            if(p.idx>q.idx) break ;
            if(cur[p.edge]>=q.weight)
            {
                rollback += D.union_edge(edges[p.edge].first,edges[p.edge].second) ;
                cur[p.edge] = -1 ;
            }
        }
        for(int &i : unused)
        {
            if(cur[i]) continue ;
            if(val[i]>=q.weight)
            {
                rollback += D.union_edge(edges[i].first,edges[i].second) ;
                cur[i] = -1 ;
            }
        }
        ans[q.idx] = D.find_siz(q.vertice) ;
        while(rollback)
        {
            D.rollback() ;
            --rollback ;
        }
        for(int &i : unused)
        {
            cur[i] = 0 ;
        }
    }
    for(query &q : upd)
    {
        val[q.edge] = q.weight ;
    }
    for(int i = 0 ; i < m ; ++i)
    {
        if(vis[edg[i].second])
        {
            edg[i].first = val[edg[i].second] , vis[edg[i].second] = 0 , cur[i] = 0 ;
        }
    }
    temp.clear() , temp_siz = 0 ;
}

int main()
{
    scanf("%d%d",&n,&m) ;
    edges.reserve(MX) ;
    edges.emplace_back(make_pair(0,0)) ;
    temp.reserve(block) ;
    for(int i = 1 ; i <= m ; ++i)
    {
        int a , b , d ;
        scanf("%d%d%d",&a,&b,&d) ;
        edges.emplace_back(make_pair(a,b)) ;
        val[i] = d ;
        edg.emplace_back(make_pair(val[i],i)) ;
    }
    int q ;
    scanf("%d",&q) ;
    for(int i = 1 ; i <= q ; ++i)
    {
        int type ;
        scanf("%d",&type) ;
        typ[i] = type ;
        if(type==1)
        {
            int b , r ;
            scanf("%d%d",&b,&r) ;
            query f = {1,0,b,r,i} ;
            temp.emplace_back(f) , ++temp_siz ;
        }
        else
        {
            int s , w ;
            scanf("%d%d",&s,&w) ;
            query f = {2,s,0,w,i} ;
            temp.emplace_back(f) , ++temp_siz ;
        }
        if(temp_siz==block) process() ;
    }
    if(temp_siz) process() ;
    for(int i = 1 ; i <= q ; ++i)
    {
        if(typ[i]==2) printf("%d\n",ans[i]) ;
    }
    return 0 ;
}

Compilation message (stderr)

bridges.cpp: In function 'int main()':
bridges.cpp:162:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  162 |     scanf("%d%d",&n,&m) ;
      |     ~~~~~^~~~~~~~~~~~~~
bridges.cpp:169:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  169 |         scanf("%d%d%d",&a,&b,&d) ;
      |         ~~~~~^~~~~~~~~~~~~~~~~~~
bridges.cpp:175:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  175 |     scanf("%d",&q) ;
      |     ~~~~~^~~~~~~~~
bridges.cpp:179:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  179 |         scanf("%d",&type) ;
      |         ~~~~~^~~~~~~~~~~~
bridges.cpp:184:18: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  184 |             scanf("%d%d",&b,&r) ;
      |             ~~~~~^~~~~~~~~~~~~~
bridges.cpp:191:18: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  191 |             scanf("%d%d",&s,&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...