zoukankan      html  css  js  c++  java
  • 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。

    2016.2.26提高时限至60s

    正解:link-cut tree+主席树。

    这题一眼看上去就不会做woc。。其实我知道一个暴力的莫队+lctO(n√nlogn)做法,不过强制在线。。

    有一个比较猎奇的做法:首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去
    并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr[i] = 0;
    这个显然是可以用LCT来弄的对吧。
    然后对于每个询问,我们的答案就是对l~r中ntr小于l的边求和,并用n减去这个值
    正确性可以YY一下:
    如果一条边的ntr >= l,那么显然他可以与从l ~ r中的边形成环,那么它对答案没有贡献
    反之如果一条边的ntr < l那么它与从l ~ r中的边是不能形成环的,那么他对答案的贡献为-1
    对于查询从l ~ r中有多少边的ntr小于l,我反正是用的函数式线段树

    ——hzwer博客

    然后还有一个特判,如果i边是自环,那nxt[i]=i,还好样例就有。。然后虽然一次AC了,这题我却写了一个多小时,LCT我都忘记写了。。

      1 //It is made by wfj_2048~
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <complex>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <cstdio>
      8 #include <vector>
      9 #include <cmath>
     10 #include <queue>
     11 #include <stack>
     12 #include <map>
     13 #include <set>
     14 #define inf (1<<30)
     15 #define N (200010)
     16 #define il inline
     17 #define RG register
     18 #define ll long long
     19 #define min(a,b) (a<b ? a : b)
     20 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
     21 
     22 using namespace std;
     23 
     24 struct edge{ int u,v; }g[N];
     25 
     26 int sum[2*N],val[2*N],lazy[2*N],ch[2*N][2],fa[2*N],st[2*N];
     27 int s[20*N],ls[20*N],rs[20*N],rt[N],nxt[N],sz,n,m,k,type,ans;
     28 
     29 il int gi(){
     30     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
     31     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
     32 }
     33 
     34 il void pushdown(RG int x){ lazy[x]=0,lazy[ch[x][0]]^=1,lazy[ch[x][1]]^=1,swap(ch[x][0],ch[x][1]); return; }
     35 
     36 il void pushup(RG int x){ 
     37     sum[x]=val[x];
     38     if (ch[x][0]) sum[x]=min(sum[x],sum[ch[x][0]]);
     39     if (ch[x][1]) sum[x]=min(sum[x],sum[ch[x][1]]);
     40     return;
     41 }
     42 
     43 il int isroot(RG int x){ return ch[fa[x]][0]!=x && ch[fa[x]][1]!=x; }
     44 
     45 il void rotate(RG int x){
     46     RG int y=fa[x],z=fa[y],k=ch[y][0]==x;
     47     if (!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z;
     48     ch[y][k^1]=ch[x][k],fa[ch[x][k]]=y;
     49     ch[x][k]=y,fa[y]=x,pushup(y),pushup(x); return;
     50 }
     51 
     52 il void splay(RG int x){
     53     RG int top=0; st[++top]=x;
     54     for (RG int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
     55     for (RG int i=top;i;--i) if (lazy[st[i]]) pushdown(st[i]);
     56     while (!isroot(x)){
     57     RG int y=fa[x],z=fa[y];
     58     if (!isroot(y)){
     59         ((ch[z][0]==y)^(ch[y][0]==x)) ? rotate(x) : rotate(y);
     60     }
     61     rotate(x);
     62     }
     63     return;
     64 }
     65 
     66 il void access(RG int x){ RG int t=0; while (x) splay(x),ch[x][1]=t,pushup(x),t=x,x=fa[x]; return; }
     67 
     68 il void makeroot(RG int x){ access(x),splay(x),lazy[x]^=1; return; }
     69 
     70 il void link(RG int x,RG int y){ makeroot(x),fa[x]=y; return; }
     71 
     72 il void cut(RG int x,RG int y){ makeroot(x),access(y),splay(y),fa[x]=ch[y][0]=0; return; }
     73 
     74 il int query(RG int x,RG int y){ makeroot(x),access(y),splay(y); return sum[y]; }
     75 
     76 il int find(RG int x){ access(x),splay(x); while (ch[x][0]) x=ch[x][0]; return x; }
     77 
     78 il void insert(RG int x,RG int &y,RG int l,RG int r,RG int v){
     79     s[y=++sz]=s[x]+1,ls[y]=ls[x],rs[y]=rs[x]; if (l==r) return; RG int mid=(l+r)>>1;
     80     v<=mid ? insert(ls[x],ls[y],l,mid,v) : insert(rs[x],rs[y],mid+1,r,v); return;
     81 }
     82 
     83 il int query(RG int x,RG int y,RG int l,RG int r,RG int v){
     84     if (l==r) return 0; RG int mid=(l+r)>>1;
     85     return v<=mid ? query(ls[x],ls[y],l,mid,v) : query(rs[x],rs[y],mid+1,r,v)+s[ls[y]]-s[ls[x]];
     86 }
     87 
     88 il void work(){
     89     n=gi(),m=gi(),k=gi(),type=gi(); RG int l,r;
     90     for (RG int i=1;i<=n;++i) val[i]=inf;
     91     for (RG int i=1;i<=m;++i) val[n+i]=i;
     92     for (RG int i=1;i<=m;++i){
     93     g[i].u=gi(),g[i].v=gi();
     94     if (g[i].u==g[i].v){ nxt[i]=i; continue; }
     95     if (find(g[i].u)==find(g[i].v)){
     96         RG int res=query(g[i].u,g[i].v);
     97         nxt[i]=res,cut(g[res].u,n+res),cut(g[res].v,n+res);
     98     }
     99     link(g[i].u,n+i),link(g[i].v,n+i);
    100     }
    101     for (RG int i=1;i<=m;++i) insert(rt[i-1],rt[i],0,m,nxt[i]);
    102     for (RG int i=1;i<=k;++i){
    103     l=gi(),r=gi(); if (type) l^=ans,r^=ans;
    104     ans=n-query(rt[l-1],rt[r],0,m,l); printf("%d
    ",ans);
    105     }
    106     return;
    107 }
    108 
    109 int main(){
    110     File("graph");
    111     work();
    112     return 0;
    113 }
  • 相关阅读:
    HDU4507 吉哥系列故事――恨7不成妻(数位dp)
    UCF Local Programming Contest 2017 G题(dp)
    ICPC Latin American Regional Contests 2019 I题
    UCF Local Programming Contest 2017 H题(区间dp)
    HDU2089 不要62
    AcWing1084 数字游戏II(数位dp)
    UCF Local Programming Contest 2017 F题(最短路)
    Google Code Jam 2019 Round 1A Pylons(爆搜+贪心)
    AcWing1083 Windy数(数位dp)
    Vue
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6477782.html
Copyright © 2011-2022 走看看