BZOJ_3514_Codechef MARCH14 GERALD07 Enhanced Edition_Chairman Tree+LCT

BZOJ_3514_Codechef MARCH14 GERALD07 Enhanced Edition_Chairman Tree+LCT

Description

For an undirected graph with N points and M edges, ask the number of connected blocks in the graph when the edges numbered in [l, r] in the graph are reserved.

Input

The first line contains four integers N, M, K, and type, which represent the number of points, the number of edges, the number of queries, and whether the query is encrypted.
The next M lines represent each edge in the graph.
The next K lines, each line of two integers L, R represent a group of queries. For the test point of type=0, the read L and R are the L and R of the inquiry; for the test point of type=1, the L and R of each group of inquiry should be L xor lastans and R xor lastans.

Output

 An integer in each row of K lines represents the number of connected blocks queried in this group.

Sample Input

3 5 4 0
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2

Sample Output

2
1
3
1

HINT

For 100% of the data, 1≤N, M, K≤200,000.


 Insert these m edges in order, and maintain the edge number with the smallest edge number.

When two points are connected, delete the one with the smallest number on the path, and record the time t of each edge deletion.

For query l~r, assuming these edges are put in, some edges will also be removed.

The number of connected blocks=n-((r-l+1)-the number of edges to be deleted).

Then know that the number of edges to be deleted is exactly those edges whose t is less than or equal to r, and you can check the chairman tree.

 

Code:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 400050
#define ls ch[p][0]
#define rs ch[p][1]
#define get(x) (ch[f[x]][1]==x)
int ch[N][2],f[N],rev[N],n,m,k,siz[N*30],t[N],val[N],mx[N],tot,cnt,lson[N*30],rson[N*30];
int xx[N],yy[N],root[N];
inline bool isrt(int p) {
    return ch[f[p]][0]!=p&&ch[f[p]][1]!=p;
}
inline void pushup(int p) {
    mx[p]=p;
    if(val[mx[ls]]>val[mx[p]]) mx[p]=mx[ls];
    if(val[mx[rs]]>val[mx[p]]) mx[p]=mx[rs];
}
inline void pushdown(int p) {
    if(rev[p]) {
        swap(ch[ls][0],ch[ls][1]); swap(ch[rs][0],ch[rs][1]);
        rev[ls]^=1; rev[rs]^=1; rev[p]=0;
    }
}
void update(int p) {
    if(!isrt(p)) update(f[p]); pushdown(p);
}
void rotate(int x) {
    int y=f[x],z=f[y],k=get(x);
    if(!isrt(y)) ch[z][ch[z][1]==y]=x;
    ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
    ch[x][!k]=y; f[y]=x; f[x]=z;
    pushup(y); pushup(x);
}
void splay(int x) {
    update(x);
    for(int d;d=f[x],!isrt(x);rotate(x))
        if(!isrt(d))
            rotate(get(d)==get(x)?d:x);
}
void access(int p) {
    int t=0;
    while(p) splay(p),rs=t,pushup(p),t=p,p=f[p];
}
void makeroot (int p) {
    access(p); splay(p); swap(ls,rs); rev[p]^=1;
}
void link(int x,int p) {
    makeroot(x); splay(p); f[x]=p;
}
void cut(int x,int p) {
    makeroot(x); access(p); splay(p); ls=f[x]=0;
}
int find(int p) {
    access(p); splay(p); while(ls) pushdown(p),p=ls;
    return p;
}
void insert(int &y,int x,int l,int r,int v) {
    y = ++ tot; you [y] = you [x] +1;
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(v<=mid) rson[y]=rson[x],insert(lson[y],lson[x],l,mid,v);
    else lson[y]=lson[x],insert(rson[y],rson[x],mid+1,r,v);
}
int query (int x, int y, int l, int r, int k) {
    if (k> = r) return you [x] -you [y];
    int mid=(l+r)>>1,re=0;
    if(1<=mid) re+=query(lson[x],lson[y],l,mid,k);
    if(k>mid) re+=query(rson[x],rson[y],mid+1,r,k);
    return re;
}
int inq (int x, int p) {
    makeroot(x); access(p); splay(p); return mx[p];
}
int main() {
    int type;
    scanf("%d%d%d%d",&n,&m,&k,&type);
    int i,x,y;
    cnt=n;
    for(i=1;i<=n;i++) mx[i]=i;
    for(i=1;i<=m;i++) {
        cnt++;
        scanf("%d%d",&x,&y); xx[cnt]=x; yy[cnt]=y;
        if(x==y) {
            t[i]=i; continue;
        }
        int t1=find(x),t2=find(y);
        if(t1!=t2) {
            val[cnt]=m-i+1; mx[cnt]=cnt;
            link(x,cnt); link(cnt,y);
        }else {
            val[cnt]=m-i+1; mx[cnt]=cnt;
            int d=inq(x,y);
            //printf("%d\n",val[d]);
            t[m-val[d]+1]=i;
             
            cut(xx[d],d); cut(d,yy[d]);
            link(x,cnt); link(cnt,y);
        }
    }
    for(i=1;i<=m;i++) {
        if(!t[i]) t[i]=m+1;
        insert(root[i],root[i-1],1,m+1,t[i]);
    }
    int ans=0;
    while(k--) {
        scanf("%d%d",&x,&y);
        if(!type) ans=0;
        x^=years; y^=years;
        ans=n-y+x-1+query(root[y],root[x-1],1,m+1,y);
        printf("%d\n",ans);
    }
    //for(i=1;i<=m;i++) printf("%d\n",t[i]);
 
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325038753&siteId=291194637