【算法总结】线性代数相关

【线性基】

〖相关资料

《关于线性基的学习与理解》        《[学习笔记]线性基》

〖注意事项

左移时记得1ll。

〖模板代码

 1 #include<cstdio>
 2 #include<algorithm> 
 3 #include<cstring>
 4 #include<cmath>
 5 #define LL long long
 6 using namespace std;
 7 const int N=55;
 8 LL n,ans,x[N],a[N];
 9 LL read()
10 {
11     LL x=0,f=1;char c=getchar();
12     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
13     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
14     return x*f;
15 }
16 int main()
17 {
18     n=read();
19     for(int i=1;i<=n;i++)x[i]=read();
20     for(int i=1;i<=n;i++)
21         for(int j=50;j>=0;j--)
22         {
23             if(!(x[i]&(1ll<<j)))continue;
24             if(!a[j]){a[j]=x[i];break;}
25             x[i]^=a[j];
26         }
27     for(int i=50;i>=0;i--)
28         if((ans^a[i])>ans)ans=ans^a[i];
29     printf("%lld",ans);
30     return 0;
31 }
View Code

〖相关题目

1.【bzoj2460】[BeiJing2011]元素

题意:见原题

分析:hzwerの博客

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long
 5 using namespace std;
 6 const int N=1e3+5;
 7 LL n,ans,bin[65],b[65];
 8 struct node{LL id;int w;}a[N];
 9 LL read()
10 {
11     LL x=0,f=1;char c=getchar();
12     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
13     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
14     return x*f;
15 }
16 bool cmp(node a,node b){return a.w>b.w;}
17 int main()
18 {
19     n=read();
20     for(int i=1;i<=n;i++)a[i].id=read(),a[i].w=read();
21     sort(a+1,a+n+1,cmp);
22     for(int i=1;i<=n;i++)
23     {
24         for(int j=63;j>=0;j--)
25             if(a[i].id&(1ll<<j))
26             {
27                 if(!b[j]){b[j]=a[i].id;break;}
28                 a[i].id^=b[j];
29             }
30         if(a[i].id)ans+=a[i].w;
31     }
32     printf("%lld",ans);
33     return 0;
34 }
View Code

2.【bzoj2115】[Wc2011] Xor

题意:给定一个边权非负的无向连通图,求从1到n的最大xor和路径,存在重边,允许经过重复点、重复边。

分析:ljh_2000の博客

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #define LL long long
 6 using namespace std;
 7 const int N=5e4+5;
 8 const int M=2e5+5;
 9 int n,m,cnt,tot,x,y,first[N];
10 LL ans,w,a[65],sum[N],cir[M];
11 bool vis[N];
12 struct edge{int to,next;LL w;}e[M];
13 LL read()
14 {
15     LL x=0,f=1;char c=getchar();
16     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
17     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
18     return x*f;
19 }
20 void ins(int u,int v,LL w){e[++cnt]=(edge){v,first[u],w};first[u]=cnt;}
21 void dfs(int x)
22 {
23     vis[x]=true;
24     for(int i=first[x];i;i=e[i].next)
25     {
26         int to=e[i].to;
27         if(!vis[to])sum[to]=sum[x]^e[i].w,dfs(to);
28         else cir[++tot]=sum[x]^e[i].w^sum[to];
29     }
30 }
31 int main()
32 {
33     n=read();m=read();
34     for(int i=1;i<=m;i++)
35     {
36         x=read();y=read();w=read();
37         ins(x,y,w);ins(y,x,w);    
38     }
39     dfs(1);ans=sum[n];
40     for(int i=1;i<=tot;i++)
41         for(int j=60;j>=0;j--)
42         {
43             if(!(cir[i]&(1ll<<j)))continue;
44             if(!a[j]){a[j]=cir[i];break;}
45             cir[i]^=a[j];
46         }
47     for(int i=60;i>=0;i--)ans=max(ans,ans^a[i]);
48     printf("%lld\n",ans);
49     return 0;
50 }
View Code

3.【codeforces724G】Xor-matic Number of the Graph

题意:给定一个边权非负的无向图,定义三元组 (u, v, s) 为有趣的,当且仅当u、v(1 ≤ u < v ≤ n)间存在一条路径异或和为s,允许经过重复点、重复边。求所有有趣的三元组的s之和。

分析:ljh_2000の博客

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define LL long long
 5 using namespace std;
 6 const int N=1e5+5;
 7 const int M=4e5+5;
 8 const int mod=1e9+7;
 9 int n,m,x,y,CNT,tot,r,tail,q[N],first[N];
10 LL w,ans,cnt[2],sum[N],two[65],a[65],cir[M];
11 bool flag,vis[N];
12 struct edge{int to,next;LL w;}e[M];
13 LL read()
14 {
15     LL x=0,f=1;char c=getchar();
16     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
17     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
18     return x*f;
19 }
20 void ins(int u,int v,LL w){e[++CNT]=(edge){v,first[u],w};first[u]=CNT;}
21 void dfs(int x,int fa)
22 {
23     vis[x]=true;q[++tail]=x;
24     for(int i=first[x];i;i=e[i].next)
25     {
26         int to=e[i].to;
27         if(to==fa)continue;
28         if(!vis[to])sum[to]=sum[x]^e[i].w,dfs(to,x);
29         else cir[++tot]=sum[x]^e[i].w^sum[to];
30     }
31 }
32 void build()
33 {
34     r=0;memset(a,0,sizeof(a));
35     for(int i=1;i<=tot;i++)
36         for(int j=60;j>=0;j--)
37         {
38             if(!(cir[i]&(1ll<<j)))continue;
39             if(!a[j]){a[j]=cir[i];break;}
40             cir[i]^=a[j];
41         }
42     for(int i=0;i<=60;i++)if(a[i])r++;
43 }
44 LL calc()
45 {
46     build();LL ans=0,now;
47     for(int i=0;i<=60;i++)
48     {
49         cnt[0]=cnt[1]=0;flag=false;
50         for(int j=0;j<=60;j++)
51             if(a[j]&(1ll<<i)){flag=true;break;}
52         for(int j=1;j<=tail;j++)
53             cnt[(sum[q[j]]>>i)&1]++;
54         now=(cnt[0]*(cnt[0]-1)/2+cnt[1]*(cnt[1]-1)/2)%mod;
55         if(flag)ans=(ans+now*two[r-1]%mod*two[i]%mod)%mod;
56         now=cnt[0]*cnt[1]%mod;
57         if(!flag)ans=(ans+now*two[r]%mod*two[i]%mod)%mod;
58         else ans=(ans+now*two[r-1]%mod*two[i]%mod)%mod;
59     }
60     return ans;
61 }
62 int main()
63 {
64     n=read();m=read();
65     for(int i=1;i<=m;i++)
66     {
67         x=read();y=read();w=read();
68         ins(x,y,w);ins(y,x,w);    
69     }
70     two[0]=1;
71     for(int i=1;i<=61;i++)two[i]=two[i-1]*2%mod;
72     for(int i=1;i<=n;i++)
73     {
74         if(vis[i])continue;
75         tot=0;tail=0;dfs(i,-1);
76         ans=(ans+calc())%mod;
77     }
78     printf("%lld",ans);
79     return 0;
80 }
View Code

 

posted @ 2018-04-19 20:43  Zsnuo  阅读(307)  评论(0编辑  收藏  举报