题目大意:给你一张$n(n\leqslant10^5)$个点$m(m\leqslant3\times10^5)$条边的无向图,每条边有一个权值,$q(q\leqslant2^{18})$次询问,每次询问给你一个$x(x<2^{18})$,问有多少个有序点对$(u,v)$,满足有一条$u$到$v$的路径异或和为$x$

题解:先建一棵生成树,把图中所有环丢进线性基,发现一条$u->v$的路径就是树上$u->v$的距离异或上一些环。

发现$x<2^{18}$,所以可以把线性基中所有可以表示出来的数求出来为集合$S$,令多项式$A(x)$,满足$[x^n]A(x)=\sum\limits_{i=1}^n[dis_i=n]$;令多项式$B(x)$,满足$[x^n]B(x)=[n\in S]$,$dis_i$表示第$i$个点到根的路径异或值

然后答案就是$A*A*B$,$*$表示异或卷积

卡点:

C++ Code:

#include <cstdio>
#include <iostream>
#define maxn 100010
#define maxm 300010
#define N 262144
const int mod = 998244353; int head[maxn], cnt;
struct Edge {
int to, nxt, w;
} e[maxm << 1];
inline void addedge(int a, int b, int c) {
e[++cnt] = (Edge) { b, head[a], c }; head[a] = cnt;
e[++cnt] = (Edge) { a, head[b], c }; head[b] = cnt;
} long long A[N], B[N];
namespace Base {
#define M 18
int p[M + 1];
inline void insert(int x) {
for (int i = M; ~i; --i) if (x >> i & 1) {
if (p[i]) x ^= p[i];
else { p[i] = x; break; }
}
}
void dfs(int dep, int val) {
if (dep > M) {
++B[val];
return ;
}
dfs(dep + 1, val);
if (p[dep]) dfs(dep + 1, val ^ p[dep]);
}
#undef M
} int n, m, q;
int dis[maxn];
bool vis[maxn];
void dfs(int u, int fa = 0) {
vis[u] = true;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (!vis[v]) {
dis[v] = dis[u] ^ e[i].w;
dfs(v, u);
} else Base::insert(dis[u] ^ dis[v] ^ e[i].w);
}
} const int lim = N;
inline void FWT(long long *A) {
for (register int mid = 1; mid < lim; mid <<= 1)
for (register int i = 0; i < lim; i += mid << 1)
for (register int j = 0; j < mid; ++j) {
const long long X = A[i + j], Y = A[i + j + mid];
A[i + j] = X + Y, A[i + j + mid] = X - Y;
}
} int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n >> m >> q;
for (int i = 0, a, b, c; i < m; ++i) {
std::cin >> a >> b >> c;
addedge(a, b, c);
}
dfs(1), Base::dfs(0, 0);
for (int i = 1; i <= n; ++i) ++A[dis[i]];
FWT(A), FWT(B);
for (int i = 0; i < lim; ++i) A[i] = A[i] * A[i] * B[i];
FWT(A);
for (int i = 0; i < lim; ++i) A[i] >>= 18;
while (q --> 0) {
static int x;
std::cin >> x;
std::cout << A[x] % mod << '\n';
}
return 0;
}

[洛谷P5169]xtq的异或和的更多相关文章

  1. ⌈洛谷4735⌋⌈BZOJ3261⌋最大异或和【可持久化01Trie】

    题目链接 [BZOJ传送门] [洛谷传送门] 题解 终于学会了可持久化trie树了.感觉并不是特别的难. 因为可持久化,那么我们就考虑动态开点的trie树. 都知道异或操作是有传递性的,那么我们就维护 ...

  2. 洛谷 [P2420] 让我们异或吧

    某两点之间的路径上所有边权的异或值即dis1^dis2--^disn. 由于x^y^y=x,所以dfs预处理出每一点到根节点的异或值,对于每次询问,直接输出 disu^disv. #include & ...

  3. 洛谷P4551 最长异或路径

    传送门:https://www.luogu.org/problem/show?pid=4551 在看这道题之前,我们应懂这道题怎么做:给定n个数和一个数m,求m和哪一个数的异或值最大. 一种很不错的做 ...

  4. 洛谷 P2420 让我们异或吧 解题报告

    P2420 让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B ...

  5. 【洛谷P4735】最大异或和

    题目大意:给定一个长度为 N 的序列,支持两个操作:在序列末尾添加一个新的数字,查询序列区间 \([l,r]\) 内使得 \(a_p\oplus a_{q+1}\oplus ... a_N\oplus ...

  6. 2018.10.26 洛谷P4551 最长异或路径(01trie)

    传送门 直接把每个点到根节点的异或距离插入01trie. 然后枚举每个点在01trie上匹配来更新答案就行了. 代码: #include<iostream> #include<cst ...

  7. 【洛谷 P4735】 最大异或和 (可持久化Trie)

    题目链接 维护整个数列的异或前缀和和\(s\),然后每次就是要求\(s[N]\text{^}x\text{^}s[k],l-1<=k<=r-1\)的最大值 如果没有\(l\)的限制,那么直 ...

  8. 洛谷P2420 让我们异或吧(树链剖分)

    题目描述异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能够 ...

  9. [洛谷P2420] 让我们异或吧

    题目链接:让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是 ...

随机推荐

  1. ORB-SLAM(八)ORBmatcher 特征匹配

    该类负责特征点与特征点之间,地图点与特征点之间通过投影关系.词袋模型或者Sim3位姿匹配.用来辅助完成单目初始化,三角化恢复新的地图点,tracking,relocalization以及loop cl ...

  2. VDI数据恢复

    环境:cirtix xendesktop 问题:VDI无法正常启动,后台登录查看报错.多次重启无效果,客户部分数据存放在启动盘. 解决方法:1.创建一台新的VDI(必须保证关机)2.将原有VDI启动盘 ...

  3. VS Help Viewer 显示内容为HTML源码的问题

    万恶的IE10 为了学习,安装了一套Windows Server 2012+SQL 2012+VS 2012的环境,整体感觉还不错,只是在使用Help Viewer查看帮助的时候,发现显示内容居然为H ...

  4. Windows运行机理——消息与消息队列

    Windows运行机理这系列文章都是来至于<零基础学Qt4编程>——吴迪,个人觉得写得很好,所以进行了搬运和个人加工 Windows程序设计时一种基于消息的时机驱动方式的设计模式,完全不同 ...

  5. NGUI制作流光效果

    效果展示: 技巧: 1.勾选UIPanel下的Normal启用UI的法线贴图,并建立带有法线贴图的UI对象(此处用NGUI自带的Reflector.Atlas中的图作为UI). 2.建立点光源并为其添 ...

  6. HDU - 6444(单调队列+思维)

    链接:HDU - 6444 题意:给出一个包含 n 个数的环,每个数都有一个价值,起点任选,每次跳顺时针跳 k 个数,在哪个数就能获得该价值(包括起点),最多取 m 次,问最少需要补充多少价值,所拿的 ...

  7. lintcode702 连接两个字符串中的不同字符

    连接两个字符串中的不同字符   给出两个字符串, 你需要修改第一个字符串,将所有与第二个字符串中相同的字符删除, 并且第二个字符串中不同的字符与第一个字符串的不同字符连接 思路:遍历两个字符串,找到互 ...

  8. [SHELL]shell中变量的使用

    1.输出变量 : #! /bin/bash my_var=BOB echo $my_var echo "hi,$my_var" echo "the price is \$ ...

  9. 正确使用memset

    今天做了一道素数打表的题我在使用一个数组记录是否为素数的时候使用了memset,将数组里面的数都清为1,代表是素数,不是素数,就改成0,我在判断这一个数是否为素数是依据也是是0还是1,结果一直存在问题 ...

  10. Thunder团队第六周 - Scrum会议5

    Scrum会议5 小组名称:Thunder 项目名称:i阅app Scrum Master:翟宇豪 工作照片: 胡佑蓉同学在拍照,所以不在照片内. 参会成员: 王航:http://www.cnblog ...