题目传送门:CF724G

题意简述:

一张 \(n\) 个点的无向图,边有边权。

定义三元组 \((u,v,w)(1\le u < v\le n)\) 合法当且仅当存在从点 \(u\) 到点 \(v\) 存在一条边权异或和为 \(w\) 的路径,经过多次的边需要算多次。

求所有合法三元组的 \(w\) 值之和对 \(10^9+7\) 取模的值。

题解:

比较简单的线性基和图结合的题目,需要用到线性基的一些基本性质。

对异或线性基在图上的应用稍有了解的同学很快可以发现结论:

  • 对于连通无向图 \(G=(V,E)\) 以及 \(G\) 的一棵生成树 \(T\):
  • \(G\) 中所有环(简单或非简单环)的异或和均可以被生成树中所有返祖边 \((x\to y)\) 对应的环 \((y\sim x\to y)\) 的异或和组成的线性基 \(B\) 表示出来。
  • 点 \(u\) 到点 \(v\) 所有路径的异或和可以被 \(T\) 中 \(u\) 到 \(v\) 的路径的异或和异或上线性基 \(B\) 表示出来。
  • 更进一步地,\(T\) 中 \(u\) 到 \(v\) 的路径的异或和等于 \(u\) 到根的路径的异或和异或 \(v\) 到根的路径的异或和。
  • 所以 \(u\) 到 \(v\) 所有路径的异或和等于 \(d_u\oplus d_v\oplus B\),其中 \(d_x\) 表示 \(x\) 到根的路径的异或和。

对于一对 \((u,v)\),尝试统计 \(d_u\oplus d_v\oplus B\) 中所有数的和。

直接做并不是很好做,考虑按位分开做:

  • 对于线性基 \(B\) 和二进制位 \(w\),有结论:
  • 设 \(B\) 中元素个数为 \(S\),则 \(B\) 可以表示出 \(2^S\) 个不同的数。
  • 如果 \(B\) 中存在二进制第 \(w\) 位为 \(1\) 的数,则那 \(2^S\) 个数中恰有 \(2^{S-1}\) 个数的二进制第 \(w\) 位为 \(1\),另外 \(2^{S-1}\) 个数的二进制第 \(w\) 位为 \(0\)。
  • 如果 \(B\) 中不存在二进制第 \(w\) 位为 \(1\) 的数,显然不可能表示出二进制第 \(w\) 位为 \(1\) 的数,全部 \(2^S\) 个数的二进制第 \(w\) 位均为 \(0\)。

    可以通过组合恒等式 \(\sum_{i=0}^{n}\binom{n}{i}[i\bmod 2=1]=\begin{cases}0&,n=0\\2^{n-1}&,n>0\end{cases}\) 证明。

统计每一位有多少种能被表示出来的方式,统计进答案即可。

这样需要枚举 \((u,v)\),其实很简单就能优化。

直接枚举二进制位 \(w\),考虑线性基 \(B\) 中是否存在二进制第 \(w\) 位为 \(1\) 的数。

如果存在,这意味着无论 \(d_u,d_v\) 的二进制第 \(w\) 位是否为 \(1\),都恰有 \(2^{S-1}\) 条使得异或和的二进制第 \(w\) 位为 \(1\) 的路径。

这意味着 \(u,v\) 可以随便选,对答案的贡献为 \(2^w2^{S-1}\binom{n}{2}\)。

如果不存在,这意味着 \(d_u,d_v\) 的二进制第 \(w\) 位必须恰有一个为 \(1\),并且此时存在 \(2^S\) 条使得异或和的二进制第 \(w\) 位为 \(1\) 的路径。

这意味着 \(d_u,d_v\) 的第 \(w\) 位必须恰有一个为 \(1\),记第 \(w\) 位为 \(1\) 的 \(d_x\) 的个数为 \(x\),对答案的贡献为 \(2^w2^Sx(n-x)\)。

最后注意原图不一定联通,对于每个联通块分别计算即可。

时间复杂度 \(\mathcal{O}(n\log^2t_i)\)。

#include <cstdio>
#include <cstring> typedef long long LL;
const int Mod = 1000000007;
const int MN = 100005;
const int MM = 400005; int N, M;
int h[MN], nxt[MM], to[MM], tot; LL w[MM];
inline void ins(int x, int y, LL z) { nxt[++tot] = h[x], to[tot] = y, w[tot] = z, h[x] = tot; } LL B[60]; int C;
inline void Add(LL x) {
for (int j = 59; ~j; --j) if (x >> j & 1)
if (!B[j]) { B[j] = x, ++C; break; }
else x ^= B[j];
} bool vis[MN];
LL d[MN];
int s[MN], t; void DFS(int u, LL v) {
vis[u] = 1, d[u] = v, s[++t] = u;
for (int i = h[u]; i; i = nxt[i]) {
if (vis[to[i]]) Add(v ^ d[to[i]] ^ w[i]);
else DFS(to[i], v ^ w[i]);
}
} LL Ans; int main() {
scanf("%d%d", &N, &M);
for (int i = 1; i <= M; ++i) {
int x, y; LL z;
scanf("%d%d%lld", &x, &y, &z);
ins(x, y, z); ins(y, x, z);
}
for (int i = 1; i <= N; ++i) if (!vis[i]) {
memset(B, 0, sizeof B), C = t = 0;
DFS(i, 0);
for (int j = 0; j < 60; ++j) {
LL c = (1ll << j) % Mod;
bool ok = 0;
for (int k = 0; k < 60; ++k) if (B[k] >> j & 1) ok = 1;
if (ok) Ans = (Ans + (LL)t * (t - 1) / 2 % Mod * ((1ll << C - 1) % Mod) % Mod * c) % Mod;
else {
int x = 0;
for (int i = 1; i <= t; ++i) if (d[s[i]] >> j & 1) ++x;
Ans = (Ans + (LL)x * (t - x) % Mod * ((1ll << C) % Mod) % Mod * c) % Mod;
}
}
}
printf("%d\n", (LL)Ans % Mod);
return 0;
}

CodeForces 724G: Xor-matic Number of the Graph的更多相关文章

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

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

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

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

  3. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  4. CF 724 G. Xor-matic Number of the Graph

    G. Xor-matic Number of the Graph 链接 题意: 给定一个无向图,一个interesting的三元环(u,v,s)满足,从u到v的路径上的异或和等于s,三元环的权值为s, ...

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

  6. Codeforces 1109D. Sasha and Interesting Fact from Graph Theory

    Codeforces 1109D. Sasha and Interesting Fact from Graph Theory 解题思路: 这题我根本不会做,是周指导带飞我. 首先对于当前已经有 \(m ...

  7. CodeForces 840B - Leha and another game about graph | Codeforces Round #429(Div 1)

    思路来自这里,重点大概是想到建树和无解情况,然后就变成树形DP了- - /* CodeForces 840B - Leha and another game about graph [ 增量构造,树上 ...

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

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

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

    题目链接 \(Description\) 给定一张带边权无向图.若存在u->v的一条路径使得经过边的边权异或和为s(边权计算多次),则称(u,v,s)为interesting triple(注意 ...

随机推荐

  1. 【Python】Python基础

    源程序文件通常以.py为扩展名 #!/usr/bin/python shebang,即执行脚本时通知内容要启动的解释器 import platform 导入模块 print platform.unam ...

  2. EF 使用 oracle

    EF 使用 oracle https://www.oracle.com/technetwork/topics/dotnet/downloads/index.html C:\Program Files ...

  3. https和http/2

    http://geek.csdn.net/news/detail/188003 HTTPS协议原理分析 HTTPS协议需要解决的问题 HTTPS作为安全协议而诞生,那么就不得不面对以下两大安全问题: ...

  4. Timus 1005 解题报告

    题目链接 http://acm.timus.ru/problem.aspx?space=1&num=1005 题目大意 给你一堆石头,现在需要你将这堆石头分成两堆,要求两堆石头的重量相差最小, ...

  5. 【科技】扩展Lucas随想

    扩展Lucas解决的还是一个很Simple的问题: 求:$C_{n}^{m} \; mod \; p$. 其中$n,m$都会比较大,而$p$不是很大,而且不一定是质数. 扩展Lucas可以说和Luca ...

  6. Java EE之通过表单上传文件

    public class Ticket { private String customerName; private String subject; private String body; priv ...

  7. Hbase(七)hbase高级编程

    一.Hbase结合mapreduce 为什么需要用 mapreduce 去访问 hbase 的数据?     ——加快分析速度和扩展分析能力     Mapreduce 访问 hbase 数据作分析一 ...

  8. D. Huge Strings Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined)

    http://codeforces.com/contest/868/problem/D 优化:两个串合并 原有状态+ 第一个串的尾部&第二个串的头部的状态 串变为第一个串的头部&第二个 ...

  9. 团体程序设计天梯赛 L1-006. 连续因子

    Two ways: 1.接近O(n) #include <stdio.h> #include <stdlib.h> #include <math.h> int ma ...

  10. QT 登陆对话框

    该文章原创于Qter开源社区(www.qter.org),作者yafeilinux,转载请注明出处! 正文 一.创建项目 1.新建Qt Gui应用,项目名称为“login”,类名和基类保持MainWi ...