• BZOJ3514 Codechef MARCH14 GERALD07加强版


    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加主席树

    解题报告:当一条边加进来的时候,如果产生了环,我们把环上最小的一条边删掉并记录,如果没有环,记录为0,到时候进行区间查询的时候,我们可以访问这个数组,如果被删掉的边小于l(0也包括),说明这条边联通了两个本来不连通的区间,然后答案-1即可,这样题目就变成了给定一个区间,求小于这个数的元素的数量,删加边显然用lct做。

      1 #include <iostream>
      2 #include <iomanip>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <cmath>
      6 #include <string>
      7 #include <cstring>
      8 #include <algorithm>
      9 #define MIN(a,b) (a<b?a:b)
     10 #define RG register
     11 const int N = 500000;
     12 const int M = 15000000;
     13 const int inf = 2147483641;
     14 
     15 using namespace std;
     16 
     17 int gi(){
     18     RG char ch=getchar();RG int x=0;
     19     while(ch<'0' || ch>'9') ch=getchar();
     20     while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
     21     return x;
     22 }
     23 
     24 int fa[N],c[2][N],rev[N],st[N],lt[N],mn[N],a[N],b[N],rt[N];
     25 int n,m,k,type,cnt;
     26 
     27 struct date{
     28     int l,r,s;
     29 }tr[M];
     30 
     31 int isroot(int x){
     32     return c[0][fa[x]]!=x && c[1][fa[x]]!=x;
     33 }
     34 
     35 void pushdown(int x){
     36     if (rev[x]==0) return;
     37     rev[x]^=1,rev[c[0][x]]^=1,rev[c[1][x]]^=1;
     38     swap(c[0][x],c[1][x]);
     39     return;
     40 }
     41 
     42 void update(int x){
     43     mn[x]=x<=n?inf:x;
     44     mn[x]=MIN(mn[x],MIN(mn[c[0][x]],mn[c[1][x]]));
     45     return;
     46 }
     47 
     48 void rotate(int x){
     49     int l,r,y=fa[x],z=fa[y];
     50     if (c[0][y]==x) l=0;
     51     else l=1;r=l^1;
     52     if (!isroot(y))
     53         if (c[0][z]==y) c[0][z]=x;
     54         else c[1][z]=x;
     55     fa[x]=z,fa[y]=x,fa[c[r][x]]=y;
     56     c[l][y]=c[r][x],c[r][x]=y;
     57     update(y),update(x);
     58     return;
     59 }
     60 
     61 void splay(int x){
     62     int tot=0;st[++tot]=x;
     63     for (RG int i=x; !isroot(i); i=fa[i]) st[++tot]=fa[i];
     64     for (RG int i=tot; i; --i) pushdown(st[i]);
     65     while(!isroot(x)){
     66         int y=fa[x],z=fa[y];
     67         if (!isroot(y))
     68             if (c[0][y]==x ^ c[0][z]==y) rotate(x);
     69             else rotate(y);
     70         rotate(x);
     71     }
     72     return;
     73 }
     74 
     75 void access(int x){
     76     int t=0;
     77     while(x){
     78         splay(x);
     79         c[1][x]=t;update(x);
     80         t=x,x=fa[x];
     81     }
     82     return;
     83 }
     84 
     85 void rever(int x){
     86     access(x),splay(x),rev[x]^=1;
     87     return;
     88 }
     89 
     90 void link(int l,int r){
     91     rever(l),fa[l]=r;
     92     return;
     93 }
     94 
     95 void cut(int l,int r){
     96     rever(l),access(r),splay(r);
     97     c[0][r]=fa[l]=0;
     98     return;
     99 }
    100 
    101 int query(int x){
    102     access(x),splay(x);
    103     while(c[0][x]) x=c[0][x];
    104     return x;
    105 }
    106 
    107 void build(int &t,int l,int r,int s){
    108     tr[++cnt]=tr[t];t=cnt;
    109     ++tr[t].s;
    110     if (l==r) return;
    111     int mid=(l+r)>>1;
    112     if (s<=mid) build(tr[t].l,l,mid,s);
    113     else build(tr[t].r,mid+1,r,s);
    114     return;
    115 }
    116 
    117 int query(int x,int l,int r,int ql,int qr){
    118     if (ql>qr) return 0;
    119     if (ql<=l && r<=qr) return tr[x].s;
    120     int ans=0,mid=(l+r)>>1;
    121     if (ql<=mid) ans+=query(tr[x].l,l,mid,ql,qr);
    122     if (qr>mid) ans+=query(tr[x].r,mid+1,r,ql,qr);
    123     return ans;
    124 }
    125 
    126 int main(){
    127     freopen("splay.in","r",stdin);
    128     freopen("splay.out","w",stdout);
    129     n=gi(),m=gi(),k=gi(),type=gi();
    130     for (RG int i=0; i<=n; ++i) mn[i]=inf;
    131     for (RG int i=1; i<=m; ++i){
    132         int l=gi(),r=gi();
    133         if (l==r) {lt[i]=m;continue;}
    134         a[i]=l,b[i]=r;
    135         if (query(l)==query(r)){
    136             rever(l),access(r),splay(r);
    137             int z=a[mn[r]-n],y=b[mn[r]-n],k=mn[r];
    138             lt[i]=mn[r]-n;
    139             cut(z,k),cut(k,y);
    140         }
    141         link(l,i+n),link(i+n,r);
    142     }
    143     for (RG int i=1; i<=m; ++i){
    144         int g=lt[i];
    145         rt[i]=rt[i-1];
    146         build(rt[i],0,m,g);
    147     }
    148     int jl=0;
    149     for (RG int i=1; i<=k; ++i){
    150         int l=gi()^jl,r=gi()^jl,ans=n;
    151         ans-=query(rt[r],0,m,0,l-1)-query(rt[l-1],0,m,0,l-1);
    152         printf("%d
    ",ans);
    153         if (type) jl=ans;
    154     }
    155     return 0;
    156 }


     

  • 相关阅读:
    代码大全第二版-阅读笔记01
    进度日报表15
    进度日报表14
    第七周总结
    进度日报表13
    进度日报表12
    进度日报表11
    系统图表联动
    算符优先分析法
    《软件需求模式》阅读笔记(一)
  • 原文地址:https://www.cnblogs.com/cjk2001/p/6484561.html
Copyright © 2020-2023  润新知