本文共 2757 字,大约阅读时间需要 9 分钟。
解决的问题是1给一堆数可不可以异或出某个数 x x x,2这堆数的最大异或和。
原理: 把原序列 A A A,转化成序列 P P P,使得 P i P_i Pi的最高位为第 i i i位,使得 A A A上的异或和的值域与 P P P上一样。构造: 对于 A A A中每新增加的一个数,都从他的最高位开始遍历 P P P,若 P i ≠ 0 P_i\not =0 Pi=0,则 v = v ⊗ P i v=v\otimes P_i v=v⊗Pi,继续一直找到不为0的 P i P_i Pi,令 P i = v P_i=v Pi=v。
void ins(LL v){ for(int i=51;i>=0;--i){ if(v&(1ll<
找某个数与 A A A最大异或和:
LL jmax(LL base=0){ LL ans=base; for(int i=51;i>=0;--i){ ans=max(ans,ans^s[i]); } return ans;}
查询某个数是否能被表示:
跟构造过程一样,若最后 v = 0 v=0 v=0,则能被表示。因为 v ⊗ x = 0 v\otimes x = 0 v⊗x=0,则 x = v x=v x=v。线性基合并
把两个线性基的数值添加到一个新的线性基中。JI merge_ji(const JI &x, const JI &y){ JI res; for(int i = 60; i >= 0; --i){ if(x.a[i])res.add(x.a[i]); if(y.a[i])res.add(y.a[i]); } return res;}
求一个无向图中点1到点n的最大异或和路径
思路#include给出两个数组 a 1... n , b 1... m a_{1...n},b_{1...m} a1...n,b1...m,求 a a a的所有长为 m m m的字串是否与 b b b数组对位异或都在线性基中。这个形式就很像KMP算法。引入一个推理。using namespace std;const int maxn=5e4+5,maxm=1e5+5;typedef long long LL;typedef struct{ int next,to; LL v;} ooo;ooo e[maxm<<1];int head[maxn];LL to[maxn];bool vis[maxn];void addEdge(int u,int v,LL d){ static int cnt=0; e[cnt]=ooo{ head[u],v,d}; head[u]=cnt++; e[cnt]=ooo{ head[v],u,d}; head[v]=cnt++;}class Ji{ LL num[66];public: void ins(LL v){ for(int i=63;i>=0;--i) if(v&(1ll< =0;--i) ans=max(ans,ans^num[i]); return ans; }}ji;void dfs(int u,LL res){ // 返祖找出所有的简单环 to[u]=res; vis[u]=true; for(int i=head[u];~i;i=e[i].next){ if(!vis[e[i].to])dfs(e[i].to,res^e[i].v); else ji.ins(res^e[i].v^to[e[i].to]); }}int main(){ int n,m; scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); int u,v; LL d; for(int i=0;i
∑ i = 1 n − m + 1 [ ( a i , a i + 1 , ⋯ , a i + m − 1 ) matches b ] ⋅ 2 i − 1 m o d ( 1 0 9 + 7 ) \sum_{i=1}^{n-m+1}\left[\left(a_{i}, a_{i+1}, \cdots, a_{i+m-1}\right) \text { matches } b\right] \cdot 2^{i-1} \bmod \left(10^{9}+7\right) i=1∑n−m+1[(ai,ai+1,⋯,ai+m−1) matches b]⋅2i−1mod(109+7)
#include#define debug(_x) cout<<#_x<<": "<<_x< >= 1; } return ans;}class Ji{ ll num[32];public: Ji(){ memset(num, 0, sizeof num); } void ins(ll v){ // 添加到线形基中 for(int i=30;i>=0;--i) if(v&(1< =0;--i){ if(num[i] && v&(1< =0;--i) if(v&(1ll< =0;--i) ans=max(ans,ans^num[i]); return ans; }};int a[maxn],b[maxn],nex[maxn];int n,m,k,ans;void getNex(){ int i=0, j=nex[0]=-1; while(i >T; while(T--){ Ji ji; ans = 0; cin>>n>>m>>k; for(int i=0;i >a[i]; for(int i=0;i >b[i]; for(int v,i=0;i >v; ji.ins(v); } for(int i=0;i
转载地址:http://agkzi.baihongyu.com/