题意

求所有点对\(u,v\),\(u\)到\(v\)所有不同的异或路径的异或值之和,对\(10^9+7\)取模

题解

求出一个dfs树,那么\(u\)到\(v\)的路径一定是树上路径异或一些环。这些环只可能是返祖边构成的,我们把所有环存到线性基里。

先把每一位拆开,答案变为:\(\sum_{i = 0}^{60} 2^i f(i)\),其中\(f(i)\)表示所有满足要求的路径中,第\(i\)位是\(1\)的路径个数

考虑\(f(i)\)怎么求。枚举\(u\)和\(v\),我们假设dfs的时候预处理了一个数组\(d\),表示到根的异或值

令\(b\)表示线性基里异或得到的数,那么问题转换为\(d[u] \text{ xor } d[v] \text{ xor } b\)有多少种情况第\(i\)位为\(1\)

再令\(x,y\)分别表示\(d[u],d[v]\)的二进制第\(i\)位,令线性基中第\(i\)位是\(1\)的个数为\(c_1\),第\(i\)位是\(0\)的个数为\(c_0\)

若\(c_1=0\),意味着线性基对答案没有贡献,随便取,对\(f(i)\)的贡献是\(2^{c_0}[x \text{ xor } y = 1]\)

若\(c_1>0\),则线性基有贡献。\(x \text{ xor } y = 1\)时\(c_1\)要取奇数个,否则取偶数个

根据组合数学,\(n\)个数里面选偶数个数和选奇数个数的方案数都是\(2^{n-1}\)

所以这种情况对\(f(i)\)的贡献是\(2^{c_0}2^{c_1-1}\)

上面的式子综合一下,\(f(i) = \sum_{1\leq u < v \leq n} ...\)(不写了)

然后我们把枚举的过程省掉。第一种情况等价于求多少对\(u,v\)异或起来第\(i\)位是\(1\),直接记录\(cnt[i]\)表示\(d[u]=i\)的\(u\)个数,然后答案就是\(\frac{cnt[i] (n - cnt[i])}{2}\)。第二种情况实际上是所有点对都适用,即为\(\frac{n(n-1)}{2}\)

这题就做完了,不过要注意一下图不一定连通,每个连通块分别求,上面公式中的\(n\)也要改为块的大小

#include <algorithm>
#include <cstdio>
using namespace std; typedef long long ll; const int N = 4e5 + 10;
const int mo = 1e9 + 7; struct Edge {
int v, nxt; ll w;
} e[N];
int n, m, hd[N], ec;
void clr() {
fill(hd + 1, hd + n + 1, -1); ec = 0;
}
void add(int u, int v, ll w) {
e[ec] = (Edge) {v, hd[u], w}; hd[u] = ec ++;
} namespace base { ll b[61];
int sz, cnt[61]; void clr() {
sz = 0;
fill(b, b + 61, 0);
fill(cnt, cnt + 61, 0);
} void ins(ll x) {
for(int i = 60; i >= 0; i --) {
if(x & (1ll << i)) {
if(b[i]) x ^= b[i];
else {
b[i] = x; sz ++;
for(int j = i - 1; j >= 0; j --) if(b[i] >> j & 1) b[i] ^= b[j];
for(int j = i + 1; j <= 60; j ++) if(b[j] >> i & 1) b[j] ^= b[i];
break ;
}
}
}
} void solve() {
for(int i = 60; i >= 0; i --) if(b[i])
for(int j = i; j >= 0; j --) if(b[i] >> j & 1) cnt[j] ++;
} } ll d[N], cnt[61], bo;
bool vis[N];
void dfs(int u, int pre = -404) {
vis[u] = 1; bo ++;
for(int i = 60; i >= 0; i --)
if(d[u] & (1ll << i)) cnt[i] ++;
for(int i = hd[u]; ~ i; i = e[i].nxt) if(i != pre) {
int v = e[i].v; ll w = e[i].w;
if(!vis[v]) {
d[v] = d[u] ^ w;
dfs(v, i ^ 1);
} else {
base :: ins(w ^ d[u] ^ d[v]);
}
}
}
int main() {
scanf("%d%d", &n, &m); clr();
int u, v; ll w;
for(int i = 1; i <= m; i ++) {
scanf("%d%d%I64d", &u, &v, &w);
add(u, v, w); add(v, u, w);
}
ll ans = 0;
for(int u = 1; u <= n; u ++) if(!vis[u]) {
base :: clr(); bo = 0; fill(cnt, cnt + 61, 0);
dfs(u); base :: solve();
for(int i = 0; i <= 60; i ++) {
ll res = 0;
if(!base :: cnt[i]) {
int c0 = base :: sz - base :: cnt[i];
res = (1ll << c0) % mo * (cnt[i] * (bo - cnt[i]) % mo) % mo;
} else {
res = (1ll << (base :: sz - 1)) % mo * (bo * (bo - 1) / 2 % mo) % mo;
}
if(res) (ans += (1ll << i) % mo * res % mo) %= mo;
}
}
printf("%d\n", (int) ans);
return 0;
}

「CF724G」Xor-matic Number of the Graph「线性基」的更多相关文章

  1. CF724G Xor-matic Number of the Graph(线性基+组合数)

    题目描述 给你一个无向图,有n个顶点和m条边,每条边上都有一个非负权值. 我们称一个三元组(u,v,s)是有趣的,当且仅当对于u,v,有一条从u到v的路径(可以经过相同的点和边多次),其路径上的权值异 ...

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

    Codeforces 题目传送门 & 洛谷题目传送门 一道还算不套路的线性基罢-- 首先由于图不连通,并且不同连通块之间的点显然不可能产生贡献,因此考虑对每个连通块单独计算贡献.按照 P415 ...

  3. 【bzoj2115】[Wc2011] Xor DFS树+高斯消元求线性基

    题目描述 输入 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图 ...

  4. 「线性基」学习笔记and乱口胡总结

    还以为是什么非常高大上的东西花了1h不到就学好了 线性基 线性基可以在\(O(nlogx)\)的时间内计算出\(n\)个数的最大异或和(不需要相邻). 上述中\(x\)表示的最大的数. 如何实现 定义 ...

  5. HDU3949:XOR(高斯消元)(线性基)

    传送门 题意 给出n个数,任意个数任意数异或构成一个集合,询问第k大个数 分析 这题需要用到线性基,下面是一些资料 1.高斯消元&线性基&Matirx_Tree定理 笔记 2.关于线性 ...

  6. 「洛谷3292」「BZOJ4568」「SCOI2016」幸运数字【倍增LCA+线性基+合并】

    [bzoj数据下载地址]不要谢我 先讲一下窝是怎么错的... \(MLE\)是因为数组开小了.. 看到异或和最大,那么就会想到用线性基. 如果不会线性基的可以参考一下我的学习笔记:「线性基」学习笔记a ...

  7. CF724G 【Xor-matic Number of the Graph】

    题目就不翻译了吧,应该写的很清楚了... 首先 \(,\) 不懂线性基的可以戳这里.知道了线性基\(,\) 但是从来没有写过线性基和图论相结合的\(,\) 可以戳这里. 好\(,\) 点完了这些前置技 ...

  8. HDU3949 XOR(线性基第k小)

    Problem Description XOR is a kind of bit operator, we define that as follow: for two binary base num ...

  9. 【BZOJ-2115】Xor 线性基 + DFS

    2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2142  Solved: 893[Submit][Status] ...

随机推荐

  1. php中的访问类型(public,private,protected)

    类型的访问修饰符允许开发人员对类成员的访问进行限制,这是PHP5的新特性.但却是oop语言的一个好的特性.而且大多数的oop语言都已支持此特性.PHP5支持三种访问修饰符: public(公有的,默认 ...

  2. Spring Boot环境的安装

    Eclipse 使用springboot框架 环境的安装 1.下载java1.8 ,安装并配置环境变量 环境变量增加java 的安装目录到环境变量中path中增加 %JAVA_HOME%/bin增加变 ...

  3. Python基础总结之第七天开始【认识函数的参数以及返回】(新手可相互督促)

    周日的早上,吃的饱饱,刷刷抖音,开始学习新一天的知识了~~~ 函数的参数: 昨天的笔记中,我们已经使用了参数,在案例中的name和sex 就是参数. 一般的函数都是有参数的,函数的参数都是放在函数定义 ...

  4. 第二章、http协议及嗅探抓包--http协议详解

    初识http协议    hypertext trandfer protocol 超文本传输协议,是一种分布式,合作式,多媒体信息系统服务,面向应用层的协议.使用最广泛的应用层协议,基于传输层的TCP协 ...

  5. 初识机器学习——概念介绍(imooc笔记)

    前言 imooc的机器学习一个最基本的介绍类课程,http://www.imooc.com/learn/717 ,不怎么涉及具体的算法或实现,只是讲了讲一些理论概念. 概述 机器学习: 利用计算机从历 ...

  6. CF网络流练习

    1. 103E 大意: 给定$n$个集合, 满足对于任意的$k$, 任意$k$个集合的并集都不少于$k$. 要求选出$k$个集合$(k> 0)$, 使得并恰好等于$k$, 输出最少花费. Hal ...

  7. .Net C# RSA签名和验签

    帮助类 using System; using System.Text; using System.IO; using System.Security.Cryptography; namespace ...

  8. Jmeter4.0---- 修改jmeter源代码(18)

    1.说明 jmeter本身功能很强大,但是在使用的时候我们会发现有些想法jmeter无法帮我们实现,这个时候就需要我们细节去修改一下它的源代码,来满足我们的需求. * 仅供参考 2.步骤 第一步: j ...

  9. HTTP协议探究(一):缓存

    一 复习与目标 1 复习 序章主要用WrieShark抓包HTTP报文 复习了TCP协议 讲述了TCP协议与HTTP之间的关系 HTTP1.1更新原因:HTTP1.0一次TCP连接只能发送一次HTTP ...

  10. Python文件操作——读写图片,音频,视频

    注意:其实就是将mode="rb"或者mode="wb",因为图片,视频,音频就是二进制进行读取,b  代表binary ,其他的和一般文件操作步骤一样,另外, ...