两点之间的任意路径都可表示为 随便某一条路径xor任何多个环,
然后可以用线性基来做,这样不会重复的,
另外必须一位一位的处理,xor是不满足结合律的
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #define MOD 1000000007 7 #define MAXN 100000+10 8 #define ll long long 9 #define pb push_back 10 #define ft first 11 #define sc second 12 #define mp make_pair 13 #define pil pair<int,ll> 14 using namespace std; 15 int n,m; 16 vector<pil> G[MAXN]; 17 ll d[MAXN]; 18 int pw[MAXN]; 19 vector<ll> vs; 20 vector<int> node; 21 void dfs(int x,ll c){ 22 d[x]=c;node.pb(x); 23 for(int i=0;i<G[x].size();i++){ 24 pil& t=G[x][i]; 25 if(-1!=d[t.ft]){vs.pb(d[x]^d[t.ft]^t.sc);} 26 else{dfs(t.ft,c^t.sc);} 27 } 28 } 29 ll a[65]; 30 ll ans; 31 ll solve(){ 32 memset(a,0,sizeof(a)); 33 int cnt=0;ll ret=0; 34 for(int i=0;i<vs.size();i++){ 35 ll v=vs[i]; 36 if(!v)continue; 37 for(int j=63;j>=0;j--){ 38 if((v>>j)&1){ 39 if(!a[j]){ 40 cnt++; 41 a[j]=v; 42 break; 43 } 44 else{ 45 v^=a[j]; 46 } 47 } 48 } 49 } 50 for(int k=0;k<=63;k++){ 51 int t[2]={0}; 52 for(int i=0;i<node.size();i++){ 53 t[(d[node[i]]>>k)&1]++; 54 } 55 bool flag=0; 56 for(int i=0;i<=63;i++){ 57 if((a[i]>>k)&1){ 58 flag=1;break; 59 } 60 } 61 ll tmp=0; 62 if(!flag){ 63 tmp+=(1LL*t[0]*t[1]%MOD*pw[cnt]%MOD); 64 tmp%=MOD; 65 tmp*=pw[k]; 66 tmp%=MOD; 67 } 68 else{ 69 tmp+=(1LL*t[0]*(t[0]-1))/2+(1LL*t[1]*(t[1]-1))/2+(1LL*t[0]*t[1]%MOD); 70 tmp%=MOD; 71 if(cnt)tmp*=pw[cnt-1],tmp%=MOD; 72 tmp*=pw[k]; 73 tmp%=MOD; 74 } 75 ret+=tmp; 76 ret%=MOD; 77 } 78 return ret; 79 } 80 int main() 81 { 82 // freopen("data.in","r",stdin); 83 pw[0]=1; 84 for(int i=1;i<=100;i++){ 85 pw[i]=pw[i-1]*2%MOD; 86 } 87 scanf("%d%d",&n,&m); 88 int x,y;ll w; 89 for(int i=1;i<=m;i++){ 90 scanf("%d%d%lld",&x,&y,&w); 91 G[x].pb(mp(y,w));G[y].pb(mp(x,w)); 92 } 93 memset(d,-1,sizeof(d)); 94 for(int i=1;i<=n;i++){ 95 if(-1==d[i]){ 96 vs.clear(),node.clear(); 97 dfs(i,0); 98 ans+=solve(); 99 ans%=MOD; 100 } 101 } 102 printf("%lld ",ans); 103 return 0; 104 }