# 3145. "APIO 2019" bridge

# 3145. "APIO 2019" bridge

Title Description

The total length of all waterways in the city of St. Petersburg and about 282 kilometers, the city's water area accounting for 7% of the urban area. - Wikipedia

Located in St. Petersburg by the \ (m \) bridges connected together \ (n-\) on the islands. With islands \ (1 \) to the \ (n-\) integer numbers, bridges \ (1 \) to \ (m \) an integer number. Each bridge connecting two different islands. Some bridges were built in the era of Peter the Great, some of which are built in the near future. This leads to different bridge may have different weight limits. More specifically, only the weight of no more than \ (d_i \) is the first car to pass \ (i \) bridges. Sometimes some of the bridges in St. Petersburg will be refurbished, but that does not necessarily make better load-bearing bridge, that is, the renovation of the bridge \ (d_i \) may increase or decrease. Are you ready to develop a product to help citizens and city guests. Currently, you develop a module to be able to perform two types of operations:

\ 1 The bridge \ (b_j \) weight limit to \ (r_j \) .

\ 2. A statistical weight \ (w_j \) car from the island \ (s_j \) Departure how many different islands can reach.

Please answer the answer to all of the second operation.

Input Format

The first line contains two integers \ (n-\) and \ (m \) - represents the number of islands and the number of bridges St. Petersburg.

Next \ (m \) lines of three integers \ (u_i, V_I, D_i \) . The first \ (I \) integer describes a connecting line island \ (u_i \) and \ (V_I \) , when the initial weight is limited to \ (D_i \) bridge.

The next line an integer \ (Q \) - indicates the number of operations.

Next \ (Q \) rows each row describes a sequential operation.

Each row of the first integer \ (t_j \) represents the type of operation:

- If \ (. 1 t_j = \) , then the operation is a first type, the next row given two integers \ (b_j \) and \ (r_j \) , represents the bridge \ (b_j \) weight limit becomes \ (r_j \) .

- If \ (t_j = 2 \) , then the operation is a second type, the next row given two integers \ (S_j \) and \ (w_j \) , expressed as a weight \ (w_j \) the cars will be from the first \ (s_j \) islands depart.

Output Format

For each of the second type of inquiry, a line output integer answer.

Data range and tips

对于全部数据, \ (1 \ k \ 5 \ Times 10 ^ 4,0 \ the m \ 10 ^ 5,1 \ the q \ 10 ^ 5 \) .保证\ (1 \ the u_i, v_i , s_j \ k, u_i \ = not v_i, 1 \ the d_i, r_j, w_j \ 10 ^ 9,1 \ the b_j \ shame, t_j \ in \ {1.2 \} \) .


We once had a modified regarded as two different sides, each side has a time existed.

The sequence of operations block, each inquiry process within each block. The inquiry \ (W \) in ascending order, will appear before the block, then this block and after the disappearance of side-by \ (W \) sort. When asked sequentially processed, these sides were added, with the path disjoint-set compression. Every time when asked for the end of time edge in this block, we then judge revoked violence whether to join, ask after. This part of the combined use according to the rank disjoint-set.

Complexity \ (O (m \ sqrt { mlog (n)}) \)

Code:

#include<bits/stdc++.h>
#define ll long long
#define N 100005

using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}

int n,m,q;

const int blk=600;
int bel[N];
struct edge {
    int x,y,w;
    int l,r;
    bool operator <(const edge &a)const {return w>a.w;}
}e[N<<1];
bool cmpe(int a,int b) {
    return e[a].w>e[b].w;
}
int etot;
int lst[N];
int op[N];
int E[N],pos[N],w[N];
vector<int>que[N/blk+5];
bool cmp(int a,int b) {return w[a]>w[b];}

int fa[N],size[N],dep[N];
int Getf(int v) {return v==fa[v]?v:fa[v]=Getf(fa[v]);}

int Getf2(int v) {
    while(v!=fa[v]) v=fa[v];
    return v;
}

void Merge(int a,int b) {
    a=Getf(a),b=Getf(b);
    if(a==b) return ;
    fa[a]=b;
    size[b]+=size[a];
}

void Init() {for(int i=1;i<=n;i++) fa[i]=i,size[i]=1,dep[i]=1;}
vector<int>tem;
int L[N],R[N];
struct node {
    int x,size,dep;
    node() {}
    node(int _x,int _size,int _dep) {x=_x,size=_size,dep=_dep;}
};
vector<node>undo;
vector<int>st,st2;
int ans[N];
void Merge(vector<int>&a,vector<int>&b) {
    static vector<int>st;
    st.clear();
    int ta=0,tb=0;
    while(ta!=a.size()||tb!=b.size()) {
        if(ta==a.size()) st.push_back(b[tb]),tb++;
        else if(tb==b.size()) st.push_back(a[ta]),ta++;
        else if(e[a[ta]].w>e[b[tb]].w) st.push_back(a[ta]),ta++;
        else st.push_back(b[tb]),tb++;
    }
    a.clear();
    for(int i=0;i<st.size();i++) a.push_back(st[i]);
}
int main() {
    n=Get(),m=Get();
    for(int i=1;i<=m;i++) {
        e[i].x=Get(),e[i].y=Get(),e[i].w=Get();
    }
    q=Get();
    for(int i=1;i<=m;i++) {
        lst[i]=i;
        e[i].l=1,e[i].r=q;
    }
    etot=m;
    int x,y;
    for(int i=1;i<=q;i++) {
        op[i]=Get();
        x=Get(),y=Get();
        if(op[i]==1) {
            E[i]=++etot;
            e[E[i]]=e[lst[x]];
            e[E[i]].w=y;
            e[lst[x]].r=i-1;
            e[E[i]].l=i;
            e[E[i]].r=q;
            lst[x]=etot;
        } else {
            pos[i]=x,w[i]=y;
        }
    }
    sort(e+1,e+1+m);
    for(int i=1;i<=m;i++) if(e[i].r) st.push_back(i);
    for(int i=1;i<=q;i++) bel[i]=(i-1)/blk+1;
    for(int i=1;i<=bel[q];i++) L[i]=(i-1)*blk+1,R[i]=min(q,i*blk);
    for(int i=1;i<=q;i++) if(op[i]==2) que[bel[i]].push_back(i);
    
    for(int i=1;i<=bel[q];i++) {
        sort(que[i].begin(),que[i].end(),cmp);
        Init();
         
        tem.clear();
        for(int j=L[i];j<=R[i];j++) if(op[j]==1) tem.push_back(E[j]);
        int tag=0;
        for(int j=0;j<que[i].size();j++) {
            int now=que[i][j];
            while(tag<st.size()&&e[st[tag]].w>=w[now]) {
                if(e[st[tag]].r>=R[i]) {
                    Merge(e[st[tag]].x,e[st[tag]].y);
                } else if(e[st[tag]].r>=L[i]) tem.push_back(st[tag]);
                tag++;
            }
            for(int k=0;k<tem.size();k++) {
                int x=e[tem[k]].x,y=e[tem[k]].y;
                Getf(x),Getf(y);
            }
            undo.clear();
            for(int k=0;k<tem.size();k++) {
                int id=tem[k];
                if(e[id].l<=now&&now<=e[id].r&&e[id].w>=w[now]) {
                    int x=Getf2(e[id].x),y=Getf2(e[id].y);
                    if(x==y) continue ;
                    undo.push_back(node(x,size[x],dep[x]));
                    undo.push_back(node(y,size[y],dep[y]));
                    if(dep[x]>dep[y]) swap(x,y);
                    fa[x]=y;
                    size[y]+=size[x];
                    if(dep[x]==dep[y]) dep[y]++;
                }
            }
            ans[now]=size[Getf2(pos[now])];
            while(undo.size()) {
                node a=undo.back();
                undo.pop_back();
                fa[a.x]=a.x;
                size[a.x]=a.size;
                dep[a.x]=a.dep;
            }
        }
        st2.clear();
        for(int j=L[i];j<=R[i];j++) if(op[j]==1) st2.push_back(E[j]);
        sort(st2.begin(),st2.end(),cmpe);
        Merge(st,st2);
    }
    for(int i=1;i<=q;i++) if(ans[i]) {
        cout<<ans[i]<<"\n";
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/hchhch233/p/11096931.html