题意

求所有点对\(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\)也要改为块的大小

  1. #include <algorithm>
  2. #include <cstdio>
  3. using namespace std;
  4. typedef long long ll;
  5. const int N = 4e5 + 10;
  6. const int mo = 1e9 + 7;
  7. struct Edge {
  8. int v, nxt; ll w;
  9. } e[N];
  10. int n, m, hd[N], ec;
  11. void clr() {
  12. fill(hd + 1, hd + n + 1, -1); ec = 0;
  13. }
  14. void add(int u, int v, ll w) {
  15. e[ec] = (Edge) {v, hd[u], w}; hd[u] = ec ++;
  16. }
  17. namespace base {
  18. ll b[61];
  19. int sz, cnt[61];
  20. void clr() {
  21. sz = 0;
  22. fill(b, b + 61, 0);
  23. fill(cnt, cnt + 61, 0);
  24. }
  25. void ins(ll x) {
  26. for(int i = 60; i >= 0; i --) {
  27. if(x & (1ll << i)) {
  28. if(b[i]) x ^= b[i];
  29. else {
  30. b[i] = x; sz ++;
  31. for(int j = i - 1; j >= 0; j --) if(b[i] >> j & 1) b[i] ^= b[j];
  32. for(int j = i + 1; j <= 60; j ++) if(b[j] >> i & 1) b[j] ^= b[i];
  33. break ;
  34. }
  35. }
  36. }
  37. }
  38. void solve() {
  39. for(int i = 60; i >= 0; i --) if(b[i])
  40. for(int j = i; j >= 0; j --) if(b[i] >> j & 1) cnt[j] ++;
  41. }
  42. }
  43. ll d[N], cnt[61], bo;
  44. bool vis[N];
  45. void dfs(int u, int pre = -404) {
  46. vis[u] = 1; bo ++;
  47. for(int i = 60; i >= 0; i --)
  48. if(d[u] & (1ll << i)) cnt[i] ++;
  49. for(int i = hd[u]; ~ i; i = e[i].nxt) if(i != pre) {
  50. int v = e[i].v; ll w = e[i].w;
  51. if(!vis[v]) {
  52. d[v] = d[u] ^ w;
  53. dfs(v, i ^ 1);
  54. } else {
  55. base :: ins(w ^ d[u] ^ d[v]);
  56. }
  57. }
  58. }
  59. int main() {
  60. scanf("%d%d", &n, &m); clr();
  61. int u, v; ll w;
  62. for(int i = 1; i <= m; i ++) {
  63. scanf("%d%d%I64d", &u, &v, &w);
  64. add(u, v, w); add(v, u, w);
  65. }
  66. ll ans = 0;
  67. for(int u = 1; u <= n; u ++) if(!vis[u]) {
  68. base :: clr(); bo = 0; fill(cnt, cnt + 61, 0);
  69. dfs(u); base :: solve();
  70. for(int i = 0; i <= 60; i ++) {
  71. ll res = 0;
  72. if(!base :: cnt[i]) {
  73. int c0 = base :: sz - base :: cnt[i];
  74. res = (1ll << c0) % mo * (cnt[i] * (bo - cnt[i]) % mo) % mo;
  75. } else {
  76. res = (1ll << (base :: sz - 1)) % mo * (bo * (bo - 1) / 2 % mo) % mo;
  77. }
  78. if(res) (ans += (1ll << i) % mo * res % mo) %= mo;
  79. }
  80. }
  81. printf("%d\n", (int) ans);
  82. return 0;
  83. }

「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. selenium登录慕课网

    from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.s ...

  2. VS2013 + Nunit 安装搭建

    Nunit 官方给我提供了Nunit 3的四种安装方式 第一种 通过NuGet进行Full Nunit安装 第二种 通过NuGet进行轻量级 NunitLite 安装 第三种 通过Zip 压缩包下载安 ...

  3. 5-MySQL DBA笔记-开发技巧

    第5章 开发技巧 本章将介绍一些和数据库相关的开发技巧.由于开发领域很广,这里只选取部分比较常见的小技巧.5.1 存储树形数据 有时我们需要保存一些树形的数据结构,比如组织架构.话题讨论.知识管理.商 ...

  4. python 画图像训练结果的loss图

    得到每个epoch的loss和predict精度后,就可以愉快地画图直观地看出训练结果和收敛性了. # coding:utf-8 import matplotlib.pyplot as plt dat ...

  5. 设置自己的bat运行文件-自己用,随时扩展

    start "" "E:\SEST_H5" start "" "C:\Program Files\Sublime Text 3\s ...

  6. 小程序page中生命周期

    onLoad -- 页面被加载出来 onShow -- 页面显示出来后  退出后两小时进来,只会执行这个生命周期 onRady -- (逻辑层传给渲染层后才会执行)监听页面初次渲染完成 onHide ...

  7. python 删除特定字符所在行

    #查询文件中含有特殊字符串的行 #!/usr/bin/python # -*- coding:utf- -*- import re file1 = open('test.txt','r+') istx ...

  8. 安装CDH5.11.2集群

    master  192.168.1.30 saver1  192.168.1.40 saver2  192.168.1.50 首先,时间同步 然后,ssh互通 接下来开始: 1.安装MySQL5.6. ...

  9. CAFFE(0):Ubuntu 下安装anaconda2和anaconda3

    这个步骤可以看做是安装caffe可以进行或者不必要的步骤,不过笔者建议安装anaconda2和anaconda3,里面会包含很多的模块,省去caffe学习过程中出现模块不存在的各种错误. 第一步.进入 ...

  10. 二十:强类型HTML辅助方法

    1. 强类型HTML辅助方法的使用 1. HTML辅助方法 例如,要输出一个文本框 @Html.TextBox("email") 2.强类型HTML辅助方法 命名规则是: HTML ...