P5227 [AHOI2013]连通图(线性基做法)

题意

神仙哈希做法。

随便找个生成树,给每个非树边赋一个值,树边的值为所有覆盖它的边的值得异或和。

删去边集使得图不联通当且即当边集存在一个子集异或和为0,可以用线性基。

证明的话好像画个图挺显然的

upd:

找到了一份详细的证明
code:

#include
using namespace std;
const int maxn=1e5+10;
const int maxm=2*1e5+10;
const int maxQ=1e5+10;
int n,m,Q,cnt;
int head[maxn],fa[maxn],sum[maxn],val[maxm],xord[40];
bool check[maxm];
struct Edge{int u,v;}E[maxm];
struct edge{int to,nxt,id;}e[maxn<<1];
vectoredge[maxQ];
inline int read()
{
    char c=getchar();int res=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
    return res*f;
}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline void add(int u,int v,int id)
{
    e[++cnt].nxt=head[u];
    head[u]=cnt;
    e[cnt].to=v;
    e[cnt].id=id;
}
void dfs(int x,int pre)
{
    for(int i=head[x];i;i=e[i].nxt)
    {
        int y=e[i].to;
        if(y==pre)continue;
        dfs(y,x);sum[x]^=sum[y];val[e[i].id]=sum[y];
    }
}
inline bool insert(int x)
{
    for(int i=31;~i;i--)
    {
        if(!(x&(1<

你可能感兴趣的:(P5227 [AHOI2013]连通图(线性基做法))