1. 程式人生 > >CF.724G.Xor-matic Number of the Graph(線性基)

CF.724G.Xor-matic Number of the Graph(線性基)

sizeof () har 構造 .com 路徑 getch tps add

題目鏈接

\(Description\)

給定一張帶邊權無向圖。若存在u->v的一條路徑使得經過邊的邊權異或和為s(邊權計算多次),則稱(u,v,s)為interesting triple。
求圖中所有interesting triple中s的和。

\(Solution\)

同[WC2011]Xor,任意兩點路徑的Xor和是它們間(任意一條)簡單路徑的和Xor一些環的和。so可以先處理出環上的和,構造線性基。兩點間的一條簡單路徑可以直接求個到根節點的dis[]。
有了各點的dis,然後考慮用組合逐位統計答案。
統計dis在這位上為0/1的點數,令size為線性基上向量個數。
如果兩個點的dis是一個0一個1,那麽要在線性基上取一個0。若線性基在這一位上有1,則保留,在剩下的\(size-1\)

個向量中任意組合,根據得到的結果可以確定這個1是否取,這樣有不同的\(2^{size-1}\)種方案;如果這位沒有1,那就是\(2^{size}\)種方案。
如果兩個點dis同為1/0,那要取一個1,如果線性基在這一位有1,同上 有\(2^{size-1}\)種方案。

註意圖可能不連通。

//343ms 11200KB
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define Bit 59
#define mod (1000000007)
typedef long long LL;
const int N=1e5+5,M=4e5+5;

int n,m,Enum,H[N],nxt[M],to[M],cnt[2],t,pw[66],size;
LL len[M],dis[N],base[66],q[N];
bool vis[N];
char IN[MAXIN],*SS=IN,*TT=IN;

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
inline LL readll()
{
    LL now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
inline void AddEdge(LL w,int u,int v)
{
    to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, len[Enum]=w;
    to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, len[Enum]=w;
}
void Insert(LL x)
{
    for(int i=Bit; ~i; --i)
        if(x>>i & 1)
        {
            if(base[i]) x^=base[i];
            else {base[i]=x, ++size; break;}
        }
}
void DFS(int x,int f)
{
    vis[x]=1, q[++t]=dis[x];
    for(int v,i=H[x]; i; i=nxt[i])
        if(!vis[v=to[i]]) dis[v]=dis[x]^len[i], DFS(v,x);
        else if(v!=f) Insert(dis[x]^dis[v]^len[i]);
}
LL Calc()
{
    LL ans=0;
    for(int i=Bit; ~i; --i)
    {
        bool flag=0; LL tmp;
        for(int j=0; j<=Bit; ++j)
            if(base[j]>>i&1) {flag=1; break;}
        cnt[0]=cnt[1]=0;
        for(int j=1; j<=t; ++j) ++cnt[q[j]>>i&1];
        if(!flag&&(!cnt[1]||!cnt[0])) continue;

        if(flag)
        {
            tmp=((1ll*cnt[0]*(cnt[0]-1)>>1)+(1ll*cnt[1]*(cnt[1]-1)>>1))%mod;
            ans+=1ll*tmp*pw[size-1]%mod*pw[i]%mod;
        }
        tmp=1ll*cnt[0]*cnt[1]%mod;
        if(flag) ans+=1ll*tmp*pw[size-1]%mod*pw[i]%mod;
        else ans+=1ll*tmp*pw[size]%mod*pw[i]%mod;
    }
    return ans%mod;
}

int main()
{
    n=read(), m=read(), pw[0]=1;
    for(int i=1; i<=Bit; ++i) pw[i]=pw[i-1]<<1, pw[i]>=mod&&(pw[i]-=mod);
    while(m--) AddEdge(readll(),read(),read());
    LL ans=0;
    for(int i=1; i<=n; ++i)
        if(!vis[i]) memset(base,0,sizeof base), size=t=0, DFS(i,i), ans+=Calc();
    printf("%I64d",ans%mod);

    return 0;
}

CF.724G.Xor-matic Number of the Graph(線性基)