zoukankan      html  css  js  c++  java
  • BZOJ3514:Codechef MARCH14 GERALD07加强版

    3514: Codechef MARCH14 GERALD07加强版

    Time Limit: 60 Sec  Memory Limit: 256 MB
    Submit: 1775  Solved: 678
    [Submit][Status][Discuss]

    Description

    N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。

    Input

    第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。
    接下来M行,代表图中的每条边。
    接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。

    Output

     K行每行一个整数代表该组询问的联通块个数。

    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

    对于100%的数据,1≤N、M、K≤200,000。

    思路{

      神级思路题.....

      首先利用LCT处理出每条边和其他边最早形成的环的编号最小的边.nxt[x]

      那么我们想:对于i∈[l,r]的边,nxt[i]∈[l,r],它不会对连通块的数量产生贡献.

      对于nxt[i]<l-1,必定连通了两个原本互不相同的连通块,cnt+1;

      那么就是n-cnt,那么要统计cnt,考虑用主席树维护每一条边连通之后的一段区间内nxt[i]的个数.

      统计历史版本l-1和当前版本r之间nxt[i]<l的个数.

    }

    #include<bits/stdc++.h>
    #define RG register
    #define il inline 
    #define N 400005
    #define rs (ch[x][1])
    #define ls (ch[x][0])
    using namespace std;
    int ch[N][2],fa[N],v[N],Min[N],st[N],nxt[N],n,m,k,flag;bool rev[N];
    bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
    void up(int x){
      Min[x]=x;
      if(rs)if(v[Min[rs]]<v[Min[x]])Min[x]=Min[rs];
      if(ls)if(v[Min[ls]]<v[Min[x]])Min[x]=Min[ls];
    }
    void down(int x){if(rev[x])rev[x]^=1,rev[rs]^=1,rev[ls]^=1,swap(rs,ls);}
    void Rotate(int x){
      int y=fa[x],z=fa[y],l,r;
      l=ch[fa[x]][1]==x,r=l^1;
      if(!isroot(y))ch[z][ch[z][1]==y]=x;
      fa[x]=z,fa[y]=x,ch[y][l]=ch[x][r],fa[ch[x][r]]=y,ch[x][r]=y;
      up(y),up(x);
    }
    void Splay(int x){int top(0),y=x;st[++top]=y;
      while(!isroot(y))st[++top]=fa[y],y=fa[y];
      for(int i=top;i;i--)down(st[i]);
      while(!isroot(x)){
        y=fa[x];int z=fa[y];
        if(!isroot(y)){
          if(ch[y][0]==x^ch[z][0]==y)Rotate(x);
          else Rotate(y);
        }Rotate(x);
      }
    }
    void access(int x){int t=0;while(x)Splay(x),ch[x][1]=t,up(x),t=x,x=fa[x];}
    int findroot(int x){access(x),Splay(x);while(ch[x][0])x=ch[x][0];return x;}
    void makeroot(int x){access(x),Splay(x),rev[x]^=1;}
    void link(int x,int y){makeroot(y),fa[y]=x;}
    void cut(int x,int y){makeroot(x),access(y),Splay(y),fa[x]=ch[y][0]=0;}
    int Query(int x,int y){makeroot(x),access(y),Splay(y);return Min[y];}
    struct ed{int u,v;}e[N];//v存该点中表示边的编号......Min则是当前节点中最小编号的点
    int l[N*30],r[N*30],tree[N*30],rt[N*30],lastans,num;
    #define mid ((L+R)>>1)
    void Insert(int y,int &x,int L,int R,int val){
      x=++num;tree[x]=tree[y]+1;if(L==R)return;
      l[x]=l[y],r[x]=r[y];if(mid<val)Insert(r[y],r[x],mid+1,R,val);
      else Insert(l[y],l[x],L,mid,val);
    }
    int Query(int y,int x,int L,int R,int val){
      if(R<=val)return tree[x]-tree[y];
      if(val<=mid)return Query(l[y],l[x],L,mid,val);
      else return Query(r[y],r[x],mid+1,R,val)+tree[l[x]]-tree[l[y]];
    }
    int main(){
      scanf("%d%d%d%d",&n,&m,&k,&flag);
      for(int i=1;i<=m;++i)scanf("%d%d",&e[i].u,&e[i].v);
      for(int i=1;i<=n;++i)Min[i]=i,v[i]=666666666;int tot=n;
      for(int i=1;i<=m;++i){int u=e[i].u,V=e[i].v;
        if(u==V){nxt[i]=i;continue;}
        if(findroot(u)==findroot(V)){
          int x=Query(u,V),y=v[x];
          nxt[i]=y;
          cut(e[y].u,x),cut(x,e[y].v);
        }tot++,Min[tot]=tot,v[tot]=i,link(u,tot),link(tot,V);
      }for(int i=1;i<=m;++i)Insert(rt[i-1],rt[i],0,m,nxt[i]);int ll,rr;
      for(int i=1;i<=k;++i){
        scanf("%d%d",&ll,&rr);if(flag)ll^=lastans,rr^=lastans;
        lastans=n-Query(rt[ll-1],rt[rr],0,m,ll-1);printf("%d
    ",lastans);
      }
      return 0;
    }
    

      

  • 相关阅读:
    python核心编程学习记录之基础知识
    VC++6.0出现no compile tool is associated with the extension.解决方法
    内存记号(Memory Trail)[自定义的名字] --调试方法
    Console 窗口
    C++ Builder创建和调用dll中的资源
    C++ builder 书籍推荐
    Qt书籍推荐
    消息队列数据结构
    Qt工程文件说明
    .obj : error LNK2001: unresolved external symbol "public: static unsigned long __stdcall ReadWrite::readData(void *)" (?readData@ReadWrite@@SGKPAX@Z)
  • 原文地址:https://www.cnblogs.com/zzmmm/p/7265842.html
Copyright © 2011-2022 走看看