CF724G. Xor-matic Number of the Graph
Posted henry-1202
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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]\)
题解
显然在同个联通块中,当前联通块中的所有环都可以被取到。而且每一条路径一定是一条简单路径与若干个环的\(xor\)和组成。
环的部分可以利用线性基来统计可以组成的不同的\(xor\)值个数。
\(dfs\)出搜索树,做树上前缀和,那么一条简单路径的\(xor\)和就是\(s[u] \oplus s[v]\),并顺便处理出所有环的\(xor\)和扔进线性基里。
因为\(xor\)对各位互不影响所以考虑按位处理。
对于第\(k\)位,将\(s\)划分为第\(k\)位为\(0\)和为\(1\)的,数量记为\(c_0\)和\(c_1\)
可以划分为\(3\)种情况:
- \(0 \oplus 0\),共\(\fracc_0\times (c_0-1)2\)种。
- \(1 \oplus 1\),共\(\fracc_1\times (c_1-1)2\)种。
- \(1 \oplus 0\),共\(c_0 \times c_1\)种。
同时线性基中也有第\(k\)位为\(0\)和第\(k\)位为\(1\)的两种情况。
几种情况分别组合一下就好。
设线性基为\(b\)。则有
- \(b[k]=0\)时,对于情况三,贡献的不同\(xor\)和为\(2^|b|\)种。对于情况一和情况二,贡献为\(0\)。
- \(b[k]=1\)时,对于情况三,贡献的不同\(xor\)和为\(2^|b|-1\)种。对于情况一和情况二,贡献为\(2^|b|-1\)种。
复杂度为\(O(n \log^2 \max(w_i))\)
#include <bits/stdc++.h>
using namespace std;
namespace io
char buf[1<<21], *p1 = buf, *p2 = buf, buf1[1<<21];
inline char gc()
if(p1 != p2) return *p1++;
p1 = buf;
p2 = p1 + fread(buf, 1, 1 << 21, stdin);
return p1 == p2 ? EOF : *p1++;
#define G gc
#ifndef ONLINE_JUDGE
#undef G
#define G getchar
#endif
template<class I>
inline void read(I &x)
x = 0; I f = 1; char c = G();
while(c < '0' || c > '9') if(c == '-') f = -1; c = G();
while(c >= '0' && c <= '9') x = x * 10LL + c - '0'; c = G();
x *= f;
template<class I>
inline void write(I x)
if(x == 0) putchar('0'); return;
I tmp = x > 0 ? x : -x;
if(x < 0) putchar('-');
int cnt = 0;
while(tmp > 0)
buf1[cnt++] = tmp % 10 + '0';
tmp /= 10;
while(cnt > 0) putchar(buf1[--cnt]);
#define in(x) read(x)
#define outn(x) write(x), putchar('\n')
#define out(x) write(x), putchar(' ')
using namespace io;
#define ll long long
const int N = 100010;
const ll mod = 1e9 + 7;
int cnt = 1, head[N];
struct edge int to, nxt; ll v; e[N<<2];
int n, m, tot;
ll s[N], b[N], ans, pw[N];
bool vis[N];
struct lb
ll p[64];
vector<ll> a;
void clear()
a.clear();
memset(p, 0, sizeof(p));
void insert(ll x)
for(ll i = 63; i >= 0; --i)
if((x >> i) & 1LL)
if(p[i]) x ^= p[i];
else
p[i] = x;
return;
void init()
for(int i = 0; i <= 63; ++i)
if(p[i])
for(int j = i - 1; j >= 0; --j)
if((p[j] >> i) & 1) p[i] ^= p[j];
for(int i = 0; i <= 63; ++i)
if(p[i]) a.push_back(p[i]);
ll solve(ll k, ll c, ll v)
bool flag = 0; v %= mod;
for(int i = 0; i < (int)a.size(); ++i)
if((a[i] >> k) & 1) flag = 1;
if(c)
if(flag) return 1LL * pw[(int)a.size() - 1] * v % mod;
return 1LL * pw[(int)a.size()] * v % mod;
else
if(flag) return 1LL * pw[(int)a.size() - 1] * v % mod;
return 0;
B;
void ins(int u, int v, ll w)
e[++cnt] = v, head[u], w;
head[u] = cnt;
void dfs(int u, int in_edge)
vis[u] = 1;
b[++tot] = s[u];
for(int i = head[u]; i; i = e[i].nxt)
int v = e[i].to;
if(in_edge == (i ^ 1)) continue;
if(vis[v])
B.insert(s[u] ^ s[v] ^ e[i].v);
continue;
s[v] = s[u] ^ e[i].v;
dfs(v, i);
ll power(ll x, ll y) ll ans = 1;
while(y)
if(y & 1) ans = ans * x % mod;
x = x * x % mod; y >>= 1;
return ans;
ll inv2 = power(2, mod - 2);
void solve()
ll c[2] = 0, 0;
for(ll k = 0; k < 64; ++k)
c[0] = c[1] = 0;
for(int i = 1; i <= tot; ++i) c[(b[i] >> k) & 1LL]++;
if(c[0]) (ans += B.solve(k, 0, (1LL << k) % mod * c[0] % mod * (c[0] - 1LL) % mod) * inv2 % mod) %= mod;
if(c[1]) (ans += B.solve(k, 0, (1LL << k) % mod * c[1] % mod * (c[1] - 1LL) % mod) * inv2 % mod) %= mod;
(ans += B.solve(k, 1, (1LL << k) % mod * c[0] % mod * c[1] % mod)) %= mod;
int main()
read(n); read(m);
for(int u, v, i = 1; i <= m; ++i)
ll w;
read(u); read(v); read(w);
ins(u, v, w), ins(v, u, w);
pw[0] = 1;
for(int i = 1; i <= n; ++i) pw[i] = pw[i - 1] * 2LL % mod;
for(int i = 1; i <= n; ++i)
if(!vis[i])
B.clear(); tot = 0;
dfs(i, 0);
B.init();
solve();
outn((ans%mod+mod)%mod);
/*
10 20
1 2 0
4 3 3
6 8 7
10 1 4
3 8 0
10 7 0
9 7 9
7 1 10
6 7 2
8 5 10
4 5 7
10 4 2
6 9 10
6 10 10
10 5 5
4 1 4
9 8 0
2 3 7
4 7 4
3 1 7
*/
以上是关于CF724G. Xor-matic Number of the Graph的主要内容,如果未能解决你的问题,请参考以下文章
CF724G Xor-matic Number of the Graph
Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS
724G - Xor-matic Number of the Graph(线性基)
CodeForces 724G: Xor-matic Number of the Graph
CodeForces - 724G Xor-matic Number of the Graph
Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) G - Xor-matic Number of the Graph 线性基好题