传送门

我咋感觉我学啥都是白学……

首先可以参考一下这一题,从中我们可以知道只要知道两点间任意一条路径以及整个图里所有环的线性基,就可以得知这两个点之间的所有路径的异或和

然而我好像并不会求线性基能张成的元素……话说原来这个在线性基里爆搜就可以了么……

于是我们可以随便选一个点为根,\(dfs\)一遍跑出个生成树,\(dis[u]\)表示点\(u\)到根节点的路径上的异或和,那么\(dis[u]\bigoplus dis[v]\)就是\(u,v\)之间的一条路径的权值,设\(x\)为一个线性基能张成的元素,那么\(dis[u]\bigoplus dis[v]\bigoplus x\)的答案就要加一

设\(q\)为线性基大小,这样的话复杂度就是\(O(n^2q)\),即枚举点对再枚举线性基能张成的元素

设数组\(A,B\),\(A[i]=1\)当且仅当\(i\)能被线性基里的元素张成否则\(A[i]=0\),\(B[i]\)为到根节点的路径的异或和为\(i\)的点的个数,于是发现答案就是\(A\times B\times B\),其中乘法表示异或卷积,用\(FWT\)优化即可

  1. //minamoto
  2. #include<bits/stdc++.h>
  3. #define R register
  4. #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
  5. #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
  6. #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
  7. template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  8. using namespace std;
  9. char buf[1<<21],*p1=buf,*p2=buf;
  10. inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
  11. int read(){
  12. R int res,f=1;R char ch;
  13. while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
  14. for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
  15. return res*f;
  16. }
  17. char sr[1<<21],z[20];int C=-1,Z=0;
  18. inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
  19. void print(R int x){
  20. if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
  21. while(z[++Z]=x%10+48,x/=10);
  22. while(sr[++C]=z[Z],--Z);sr[++C]='\n';
  23. }
  24. const int N=3e5+5,P=998244353,inv=499122177;
  25. inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
  26. inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
  27. inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
  28. int ksm(R int x,R int y){
  29. R int res=1;
  30. for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
  31. return res;
  32. }
  33. struct eg{int v,nx,w;}e[N<<1];int head[N],tot;
  34. inline void add_edge(R int u,R int v,R int w){e[++tot]={v,head[u],w},head[u]=tot;}
  35. int p[105],dis[N],vis[N],is[N],a[N];
  36. int mx,lim,n,m,q,u,v,w,c;
  37. void dfs(int u){
  38. vis[u]=1;
  39. go(u)if(!vis[v])dis[v]=dis[u]^e[i].w,dfs(v);
  40. else is[dis[v]^dis[u]^e[i].w]=1;
  41. }
  42. void ins(R int x){
  43. fd(i,mx-1,0)if(x&(1<<i)){
  44. if(p[i])x^=p[i];
  45. else return (void)(p[i]=x);
  46. }
  47. }
  48. void find(int i,int x){
  49. if(i<0)return (void)(is[x]=1);
  50. find(i-1,x);if(p[i])find(i-1,x^p[i]);
  51. }
  52. void FWT(int *A,int ty){
  53. for(R int mid=1;mid<lim;mid<<=1)
  54. for(R int j=0;j<lim;j+=(mid<<1))
  55. for(R int k=0;k<mid;++k){
  56. int x=A[j+k],y=A[j+k+mid];
  57. A[j+k]=add(x,y),A[j+k+mid]=dec(x,y);
  58. if(ty==-1)A[j+k]=mul(A[j+k],inv),A[j+k+mid]=mul(A[j+k+mid],inv);
  59. }
  60. }
  61. int main(){
  62. // freopen("testdata.in","r",stdin);
  63. n=read(),m=read(),q=read();
  64. while(m--)u=read(),v=read(),w=read(),add_edge(u,v,w),add_edge(v,u,w),cmax(lim,w);
  65. while(lim)++mx,lim>>=1;
  66. lim=(1<<mx);dfs(1);
  67. fp(i,0,lim-1)if(is[i])ins(i);
  68. find(mx-1,0);
  69. fp(i,1,n)++a[dis[i]];
  70. FWT(is,1),FWT(a,1);fp(i,0,lim-1)a[i]=mul(mul(a[i],a[i]),is[i]);
  71. FWT(a,-1);
  72. while(q--)c=read(),print(a[c]);
  73. return Ot(),0;
  74. }

P5169 xtq的异或和(FWT+线性基)的更多相关文章

  1. LOJ114_k 大异或和_线性基

    LOJ114_k 大异或和_线性基 先一个一个插入到线性基中,然后高斯消元. 求第K小就是对K的每一位是1的都用对应的线性基的一行异或起来即可. 但是线性基不包含0的情况,因此不能确定能否组成0,需要 ...

  2. [洛谷P5169]xtq的异或和

    题目大意:给你一张$n(n\leqslant10^5)$个点$m(m\leqslant3\times10^5)$条边的无向图,每条边有一个权值,$q(q\leqslant2^{18})$次询问,每次询 ...

  3. LOJ114 k大(xiao)异或和(线性基)

    构造线性基后将其消至对任意位至多只有一个元素该位为1.于是就可以贪心了,将k拆成二进制就好.注意check一下是否能异或出0. #include<iostream> #include< ...

  4. AcWing 228. 异或 (dfs+线性基)打卡

    题目:https://www.acwing.com/problem/content/230/ 题意:有一个图,每条边有一个权值,现在求1-n的一条路径的最大异或和,一条边能经过多次,相应的也要计算那么 ...

  5. 线性空间和异或空间(线性基)bzoj4004贪心+高斯消元优秀模板

    线性空间:是由一组基底构成的所有可以组成的向量空间 对于一个n*m的矩阵,高斯消元后的i个主元可以构成i维的线性空间,i就是矩阵的秩 并且这i个主元线性无关 /* 每个向量有权值,求最小权极大线性无关 ...

  6. 洛谷.3733.[HAOI2017]八纵八横(线性基 线段树分治 bitset)

    LOJ 洛谷 最基本的思路同BZOJ2115 Xor,将图中所有环的异或和插入线性基,求一下线性基中数的异或最大值. 用bitset优化一下,暴力的复杂度是\(O(\frac{qmL^2}{w})\) ...

  7. 【线性基/神仙题】P4151 [WC2011]最大XOR和路径

    Description 给定一个无向连通图,边有边权,求一个 \(1~\sim n\) 的路径,最大化边权的异或和.如果一条边经过多次则计算多次. Input 第一行是两个整数 \(n,m\) 代表点 ...

  8. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  9. BZOJ 2115 Xor(线性基)

    题意:给定一个n<=50000个点m<=100000条边的无向联通图,每条边上有一个权值wi<=1e18.请你求一条从1到n的路径,使得路径上的边的异或和最大. 任意一条1到n的路径 ...

随机推荐

  1. 源代码方式向openssl中加入新算法完整具体步骤(演示样例:摘要算法SM3)【非engine方式】

    openssl简单介绍 openssl是一个功能丰富且自包括的开源安全工具箱.它提供的主要功能有:SSL协议实现(包括SSLv2.SSLv3和TLSv1).大量软算法(对称/非对称/摘要).大数运算. ...

  2. HBuilder开发App教程06-首页

    实战 前面几节基本是一些概念的普及, 正如前面提到的,本教程会以滴石作为范例进行解说, 有兴趣的能够先行下载体验一下.或者下载源代码研究下. 新建项目 打开HBuilder,在项目管理器中右键--新建 ...

  3. PostgreSQL源码解读 基础结构 node

    一.node节点的定义 源代码路径postgresql-9.2.3/src/include/nodes/nodes.h 在查询解析SQL的查询部分,要用到大量的结构体,许多函数处理的逻辑类似,就是传入 ...

  4. Bean定义并注册到spring

    1.XML配置文件 2.Annotation注解 3.Java Code 配置方式 BeanDefinitionRegistryPostProcessor

  5. html使用代码大全

    <DIV style="FONT-SIZE: 9pt">1)贴图:<img src="图片地址">1)首行缩进2格:<p styl ...

  6. Java 内存区域与内存溢出异常

    一.Java虚拟机内存划分 1.程序计数器 线程私有 可以看做是当前线程所执行的字节码的行号指示器.字节码解释器工作时是通过改变这个计数器的值来选取下一条需要执行的字节码指令. Java虚拟机是通过多 ...

  7. luogu3384 【模板】 树链剖分

    题目大意 已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作:操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z操作2: 格式: 2 x ...

  8. 记录001:AS11 BAPI

    未知元素(174657434)  15:05:41AS11有没有BAPI呀?有做过的吗 BAPI_FIXEDASSET_OVRTAKE_CREATE

  9. JOptionPane常用提示框

    //JOptionPane.showMessageDialog(parentComponent, message, title, messageType, icon); JOptionPane.sho ...

  10. IRRIGATION LINES

    IRRIGATION LINES Time Limit: 2000ms, Special Time Limit:5000ms, Memory Limit:65536KB Total submit us ...