题目链接

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

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

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

    G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组 ...

  2. CodeForces - 724G:Xor-matic Number of the Graph

    两点之间的任意路径都可表示为  随便某一条路径xor任何多个环, 然后可以用线性基来做,这样不会重复的, 另外必须一位一位的处理,xor是不满足结合律的 #include<cstdio> ...

  3. 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 ...

  4. codeforces 724G - Xor-matic Number of the Graph 线性基+图

    题目传送门 题意:给出衣服无向带权图,问有多少对合法的$<u,v,s>$,要求$u$到$v$存在一条路径(不一定是简单路径)权值异或和等于$s$,并且$u<v$.求所有合法三元组的s ...

  5. codeforces 1101G (Zero XOR Subset)-less 前缀异或+线性基

    题目传送门 题意:给出一个序列,试将其划分为尽可能多的非空子段,满足每一个元素出现且仅出现在其中一个子段中,且在这些子段中任取若干子段,它们包含的所有数的异或和不能为0. 思路:先处理出前缀异或,这样 ...

  6. Educational Codeforces Round 58 (Rated for Div. 2) G 线性基

    https://codeforces.com/contest/1101/problem/G 题意 一个有n个数字的数组a[],将区间分成尽可能多段,使得段之间的相互组合异或和不等于零 题解 根据线性基 ...

  7. Codeforces.472F.Design Tutorial: Change the Goal(构造 线性基 高斯消元)

    题目链接 \(Description\) 给定两个长为\(n\)的数组\(x_i,y_i\).每次你可以选定\(i,j\),令\(x_i=x_i\ \mathbb{xor}\ x_j\)(\(i,j\ ...

  8. bzoj 2115 [Wc2011] Xor 路径最大异或和 线性基

    题目链接 题意 给定一个 \(n(n\le 50000)\) 个点 \(m(m\le 100000)\) 条边的无向图,每条边上有一个权值.请你求一条从 \(1\)到\(n\)的路径,使得路径上的边的 ...

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

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 异或两次同一段路径的权值,就相当于没有走这段路径: 由此可以得到启发,对于不同的走法, ...

随机推荐

  1. 简单对象List自定义属性排序

    <body> <div> sort()对数组排序,不开辟新的内存,对原有数组元素进行调换 </div> <div id="showBox" ...

  2. python 面试题4

    Python面试题 基础篇 分类: Python2014-08-08 13:15 2071人阅读 评论(0) 收藏 举报 最近,整理了一些python常见的面试题目,语言是一种工具,但是多角度的了解工 ...

  3. http、https 等 常用默认端口号

    ⑴. HTTP协议代理服务器常用端口号:80/8080/3128/8081/9080⑵. SOCKS代理协议服务器常用端口号:1080⑶. FTP(文件传输)协议代理服务器常用端口号:21⑷. Tel ...

  4. openjudge-NOI 2.5-1789 算24

    题目链接:http://noi.openjudge.cn/ch0205/1789/ 题解: 并不是非常简单的搜索,需要考虑一些东西…… 首先有运算符优先级的限制,还有括号,数字的顺序也可以调整,如果只 ...

  5. HDU 6212 Zuma 2017青岛网络赛 区间DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6212 解法:看了眼题就发现这个BZOJ 1032不是一毛一样?但是BZOJ上那是个巨坑,数据有错,原来 ...

  6. Java与redis交互、Jedis连接池JedisPool

    Java与redis交互比较常用的是Jedis. 先导入jar包: commons-pool2-2.3.jar jedis-2.7.0.jar 基本使用: public class RedisTest ...

  7. Python基础 - 正则表达式

    Python自带正则表达式模块,即re模块. 导入正则模块: import re 用dir()函数查看re模块内的属性和方法: dir(re)

  8. Oracle学习笔记:实现select top N的方法

    由于Oracle不支持select top N语句,所以在Oracle中需要利用order by和rownum的组合来实现select top N的查询. rownum是记录表中数据编号的一个隐藏字段 ...

  9. 2016-2017-2 20155309南皓芯《java程序设计》第十周学习总结

    教材内容总结 网络编程 定义:网络编程就是在两个或两个以上的设备之间传输数据. 计算机网络概述: 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. 网络中的每个设备都会有一个唯一的数 ...

  10. Java MongoDB : Save image example

    In this tutorial, we show you how to save an image file into MongoDB, via GridFS API. The GridFS API ...