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

题目链接

\(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;
}

原文地址:https://www.cnblogs.com/SovietPower/p/9307422.html

时间: 2024-09-30 06:25:46

CF.724G.Xor-matic Number of the Graph(线性基)的相关文章

Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS

G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组(u,v,s)表示u到v的(不一定为简单路径)路径上xor值为s.求出这张无向图所有不重复三元组的s之和.1≤n≤10^5,1≤m≤2*10^5. 想法: 如果做过[Wc2011 xor]这道题目(题解),那么问题变得简单起来了. ①假设我们钦定一个(u,v),设任意一条u->v的路径xor值为X,

Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) G - Xor-matic Number of the Graph 线性基好题

G - Xor-matic Number of the Graph 上一道题的加强版本,对于每个联通块需要按位算贡献. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define ull unsigned lo

bzoj2115 [Wc2011] Xor——高斯消元 &amp; 异或线性基

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 异或两次同一段路径的权值,就相当于没有走这段路径: 由此可以得到启发,对于不同的走法,也许只需要找出一些东西,就可以把所有的走法用它们来异或表示出来: 再关注图上的环路,因为从 1 到 n 的不同路径也可以看作是经由 1 和 n 连接的环路,路径上也可能有环路: 发现对于环路的不同走法,就是把路与环的权值异或求最优值,重叠的部分异或了两次相当于不走: 于是问题转化为找出图上的所有环(

724G - Xor-matic Number of the Graph(线性基)

724G - Xor-matic Number of the Graph 题意: 待补~~ 参考http://www.cnblogs.com/ljh2000-jump/p/6443189.html

CodeForces - 724G Xor-matic Number of the Graph

Discription You are given an undirected graph, constisting of n vertices and m edges. Each edge of the graph has some non-negative integer written on it. Let's call a triple (u,?v,?s) interesting, if 1?≤?u?<?v?≤?n and there is a path (possibly non-si

【CF 566F】 Clique in the Divisibility Graph

[CF 566F] Clique in the Divisibility Graph 最大团模型的dp 数做点 能约分的一对数间有路 问最大团(最大完全子图) 用最长公共子序列做法 dp出最长路 由于一个数约数的约数也是这个数的约数 所以只要能连起来就是个完全子图 代码如下: #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <alg

CF724G 【Xor-matic Number of the Graph】

题目就不翻译了吧,应该写的很清楚了... 首先 $,$ 不懂线性基的可以戳这里.知道了线性基$,$ 但是从来没有写过线性基和图论相结合的$,$ 可以戳这里. 好$,$ 点完了这些前置技能之后,我们就可以来愉快的切题啦! 正片$:$ 类比$[WC$ $2011]$ 最大$xor$和路径$,$ 我们肯定要找环$,$ 找完环后再用环去构造线性基$,$ 因为还是那句话嘛$:$ 任何一条复杂路径$,$ 都能有起始两点的一条简单路径再加上若干个环组成. 那么接下来的问题就是$:$如何求出亦或值的和? $en

CF724G. Xor-matic Number of the Graph

题意 http://codeforces.com/contest/724/problem/G 定义三元组\((u,v,s)(u<v)\):\(u\)到\(v\)的路径的\(xor\)和为\(s\)(可以不是简单路径),\((u,v,s)\)不同当且仅当\(u,v,s\)的其中一个参数不同. 求所有不同三元组的\(s\)值之和. \(n \in [1,10^5],m\in [0, 2\cdot 10^5], w\in [0,10^{18}]\) 题解 显然在同个联通块中,当前联通块中的所有环都可以

HDU3949 XOR(线性基第k小)

Problem Description XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A XOR B, then for each bit of C, we can get its value by check the digit of corresponding position in A and B. And for each digit,