bzoj 3569: DZY Loves Chinese II
阿新 • • 發佈:2018-10-22
-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