bzoj 3569: DZY Loves Chinese II

Posted tyher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3569: DZY Loves Chinese II相关的知识,希望对你有一定的参考价值。

链接 3569: DZY Loves Chinese II

  • 题目大意:给出一张(n)个点(m)条边的无向图,进行(q)次询问,问删掉某(k)条边后图是否联通,强制在线。
  • (N≤100000 M≤500000 Q≤50000 1≤K≤15)
  • 先考虑一下离线怎么做:
  • (cdq)分治。
  • 首先把所有没有影响的边都建出来
  • 分治过程:
  • 1、把左边没有右边有的边建出来
  • 2、分治左边
  • 3、把并查集恢复至初始的样子
  • 4、把右边没有左边有的边建出来
  • 5、分治右边
  • 虽然每次(cdq)的过程中,都暴力判断了每个询问中的边集合的划分情况,但是复杂度是类似于线段树递归的
  • 所以总复杂度还是(O(qklogq))
  • 有个细节就是,如何将并查集恢复至初始的样子?
  • 每当一个点的父亲被修改时,将它和它的父亲入栈,每次只需要记录一下当前过程对应在栈的哪个位置即可
  • 这样就顺带把[Ahoi2013]连通图切掉了
  • 强制在线怎么做?
  • 我们首先可以求出一棵生成树,然后边就有树边和非树边。
  • 对于一条非树边,我们给它赋一个随机的权值。
  • 然后对于每条树边,它的权值就是所有覆盖这条树边的非树边的权值的异或和。
  • 具体如何搞出树边的权值呢:
  • 树上差分一下,在每条非树边的两端打上标记,树边的权值就是y的子树的异或和。
  • 当然你想写一个树剖也可以
  • 这样我们可以发现,如果这条树边和所有覆盖它的非树边都删除了,就一定不会联通,而都删除代表选出的这些边的异或和为0。
  • 那么问题变成了每次给出一个边集问是否有某个子集的异或和为0。
  • 线性基维护一下即可。
  • 复杂度(O(n+qklog(1e9)))
#include<bits/stdc++.h>
#define R register int
#define ll long long
#define uLL unsigned long long 
using namespace std;
const int N=2000001;
const int M=1000001;
int n,m,cnt,vis[N],nt[M],to[M],hd[N],p,flag;
uLL num[M],vl[N],Bas[35];
struct ed{int u,v,us;}G[M];
void link(R f,R t){nt[++cnt]=hd[f],to[cnt]=t,hd[f]=cnt;}
uLL rnd() { return (((uLL)rand())<<32)^((uLL)rand()<<16)^rand(); }
int gi(){
    R x=0,k=1;char c=getchar();
    while((c<‘0‘||c>‘9‘)&&c!=‘-‘)c=getchar();
    if(c==‘-‘)k=-1,c=getchar();
    while(c>=‘0‘&&c<=‘9‘)x=(x<<3)+(x<<1)+c-‘0‘,c=getchar();
    return x*k;
}
void Dfs1(R i,R e){
    vis[i]=1;
    for(R k=hd[i];k;k=nt[k])
        if(!vis[to[k]])
            G[k>>1].us=1,Dfs1(to[k],i);
}
void Dfs2(R i){
    vis[i]=1;
    for(R k=hd[i];k;k=nt[k])
        if(!vis[to[k]]){
            Dfs2(to[k]),vl[k>>1]=num[to[k]];
            num[i]^=num[to[k]];
        }
}
void ins(R x){
    for(R j=0;j<=30;++j){
        (!x)?flag=1:0;
        if((1<<j)&x){
            if(!Bas[j]){Bas[j]=x;return;}
            else x^=Bas[j];
        }
    }
}
int main(){
    freopen("chi.in","r",stdin);
    freopen("chi.out","w",stdout);
    srand(time(NULL));
    n=gi(),m=gi(),cnt=1;
    for(R i=1;i<=m;++i){
        G[i].u=gi(),G[i].v=gi();
        link(G[i].u,G[i].v),link(G[i].v,G[i].u);
    }
    Dfs1(1,0);
    for(R i=1;i<=m;++i)
        if(!G[i].us){
            vl[i]=rnd();
            num[G[i].u]^=vl[i],num[G[i].v]^=vl[i];
        }
    memset(vis,0,sizeof(vis));
    Dfs2(1);R u=0,q=gi(),v;
    while(q--){
        p=gi(),flag=0,memset(Bas,0,sizeof(Bas));
        for(R j=1;j<=p;++j)v=gi()^u,ins(vl[v]);
        if(!flag)u++,puts("Connected");
        else puts("Disconnected");
    }
    return 0;
}

以上是关于bzoj 3569: DZY Loves Chinese II的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 3569: DZY Loves Chinese II

bzoj3569 DZY Loves Chinese II

BZOJ3569 DZY Loves Chinese II

bzoj3569 DZY Loves Chinese II

bzoj3569 DZY Loves Chinese II

BZOJ 3569 DZY Loves Chinese II