Submission #1033198

#TimeUsernameProblemLanguageResultExecution timeMemory
1033198ASN49K다리 (APIO19_bridges)C++14
100 / 100
2507 ms13068 KiB
#define LOCAL 1
#include <bits/stdc++.h>
using namespace std;
using i64=long long;
#define all(x) x.begin(),x.end()
#define pb push_back
#define UNSET -1
const int N = 50'000;
const int SQRT=230;
namespace dsu_roll_back
{
    static int t[N],sz[N];
    static int sk[N],sk_size;
    void roll_back()
    {
        while(sk_size>0)
        {
            sz[t[sk[sk_size-1]]]-=sz[sk[sk_size-1]];
            t[sk[sk_size-1]]=sk[sk_size-1];
            sk_size--;
        }
    }
    int root(int x)
    {
        if(t[x]!=x)
        {
            return root(t[x]);
        }
        return x;
    }
    void unite(int x,int y,bool roll)
    {
        x=root(x);
        y=root(y);
        if(sz[x]<sz[y])
        {
            swap(x,y);
        }
        if(x==y)
        {
            return;
        }
        t[y]=x;
        sz[x]+=sz[y];
        if(roll)
        {
            sk[sk_size++]=y;
        }
    }
    void init(int n)
    {
        fill(sz,sz+n,1);
        iota(t,t+n , 0);
        sk_size=0;
    }
    int size(int x)
    {
        return sz[root(x)];
    }
}
//do not edge kids
struct edge
{
    int x,y,weight;
    bool operator ==(const edge& b)const
    {
        return x==b.x && y==b.y && weight==b.weight;
    }
};
struct query
{
    int tip,poz,weight,rez;
};
static int n,m,q;
static vector<edge>edges;
static vector<query>querys;
static set<pair<int,int>>mp;
int old[N];

void solve_batch(const int l,const int r)
{
    vector<bool>appears(m,false);
    for(int i=l;i<r;i++)
    {
        if(querys[i].tip==1)
        {
            appears[querys[i].poz]=true;
        }
    }

    vector<int>good;
    vector<int>bad;
    good.reserve(n);
    bad.reserve(r-l+1);
    for(auto &c:mp)
    {
        if(!appears[c.second])
        {
            good.pb(c.second);
        }
        else
        {
            bad.pb(c.second);
        }
    }
    for(auto &c:bad)
    {
        mp.erase({-edges[c].weight , c});
    }
    vector<int>ord_querys(r-l,0);
    iota(all(ord_querys) , l);
    sort(all(ord_querys) , [&](int x,int y){
        if(querys[x].weight==querys[y].weight)
        {
            return querys[x].tip<querys[y].tip;
        }
        return querys[x].weight>querys[y].weight;
    });
    vector<int>::iterator it_good=good.begin();
    vector<int>::iterator it_ord_querys=ord_querys.begin();

    dsu_roll_back::init(n);

    for(;it_ord_querys!=ord_querys.end();it_ord_querys++)
    {
        if(querys[*it_ord_querys].tip==1)
        {
            continue;
        }
        for(;it_good!=good.end() && edges[*it_good].weight>=querys[*it_ord_querys].weight;it_good++)
        {
            dsu_roll_back::unite(edges[*it_good].x , edges[*it_good].y ,false);
        }
        for(int i=l;i<*it_ord_querys;i++)
        {
            if(querys[i].tip==1)
            {
                old[i-l]=edges[querys[i].poz].weight;
                edges[querys[i].poz].weight=querys[i].weight;
            }
        }
        for(auto &c:bad)
        {
            if(edges[c].weight>=querys[*it_ord_querys].weight)
            {
                dsu_roll_back::unite(edges[c].x , edges[c].y , true);
            }
        }
        querys[*it_ord_querys].rez=dsu_roll_back::size(querys[*it_ord_querys].poz);
        for(int i=*it_ord_querys-1;i>=l;i--)
        {
            if(querys[i].tip==1)
            {
                edges[querys[i].poz].weight=old[i-l];
            }
        }
        dsu_roll_back::roll_back();
    }

    for(int i=l;i<r;i++)
    {
        if(querys[i].tip==1)
        {
            edges[querys[i].poz].weight=querys[i].weight;
        }
    }
    for(auto &c:bad)
    {
        mp.insert({-edges[c].weight , c});
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin>>n>>m;
    edges.resize(m);
    for(int i=0;i<m;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        x--;
        y--;
        mp.insert({-z , i});
        edges[i]={x,y,z};
    }
    cin>>q;
    querys.resize(q);
    for(int i=0;i<q;i++)
    {
        cin>>querys[i].tip>>querys[i].poz>>querys[i].weight;
        querys[i].poz--;
    }
    for(int i=0;i<q;i+=SQRT)
    {
        solve_batch(i,min(i+SQRT,q));
    }
    for(int i=0;i<q;i++)
    {
        if(querys[i].tip==2)
        {
            cout<<querys[i].rez<<'\n';
        }
    }
}
#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...