1. 程式人生 > >bzoj 3569: DZY Loves Chinese II

bzoj 3569: DZY Loves Chinese II

-i bits using ahoi2013 就是 -- include strong sign

鏈接 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