本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

题目链接:codeforces724G

正解:线性基
解题报告:

  一道线性基好题…

  是不是感觉和$WC2011$的那道题有相通之处呢?首先搞出一棵$dfs$树,并且得到树上每个环的$xor$值。

  我们发现,两点间就是本来的$dis$ $xor$ 某些环的$xor$值,即可组合得到一些新的异或值。位运算的题目,我们显然按位来做。

  首先,对于两个这一位同时为$1$或者同时为$0$的,我们考虑若要有贡献,必须是从环上得到一个这一位为$1$的$xor$值,如果线性基这一位都是$0$则无贡献,否则我们可以考虑,假设线性基中有$r$个向量,那么我们把这一位为$1$的一个向量排除在外,剩下的随便选,任意组合,也就是$2^{r-1}$,得到一个权值,再根据得到的权值这一位是$1$还是$0$,来决定被排除在外的这个向量选不选,所以贡献就是$2^{r-1}$。

  同理,如果一个是$1$一个是$0$,那么我同样是分类讨论,向量中有无这一位是$1$的,分别算贡献即可。

//It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <complex>
using namespace std;
typedef long long LL;
typedef long double LB;
typedef complex<double> C;
const double pi = acos(-1);
const int mod = 1000000007;
const int MAXN = 200011;
const int MAXM = 400011;
int n,m,ecnt,first[MAXN],to[MAXM],next[MAXM],scnt,dui[MAXN],cir_cnt,r;
LL dis[MAXN],w[MAXM],p[70]/*!!!不要开大了...*/,cir[MAXM],ans,fp[MAXM<<1],cnt[2];//数组不要开小了!!!
bool vis[MAXN],in[MAXN];
inline void link(int x,int y,LL z){ next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; w[ecnt]=z; }
inline LL fast_pow(LL x,LL y){ LL r=1; while(y>0) { if(y&1) r*=x,r%=mod; x*=x; x%=mod; y>>=1; } return r; }
inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline LL getlong(){
LL w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void dfs(int x,LL dd,int fa){
if(dis[x]==-1) dis[x]=dd;
else {//找环
cir[++cir_cnt]=dd^dis[x];
return ;
}
vis[x]=1; dis[x]=dd; dui[++scnt]=x;
for(int i=first[x];i;i=next[i]) {
int v=to[i]; if(v==fa) continue;
dfs(v,dd^w[i],x);
}
} inline void build(){//构线性基
memset(p,0,sizeof(p)); r=0;
for(int i=1;i<=cir_cnt;i++) {
for(int j=62;j>=0;j--) {
if(!(cir[i]>>j)) continue;
if(!p[j]) { p[j]=cir[i]; break; }
cir[i]^=p[j];
}
}
for(int j=0;j<=62;j++) if(p[j]!=0) r++;//计算线性基有效的向量个数
} inline LL calc(){
build(); LL tot=0,now; bool flag;
for(int i=0;i<=62;i++) {//按位算贡献
cnt[0]=cnt[1]=0; flag=false;//是否存在某个向量的这一位为1
for(int j=0;j<=62;j++) if((p[j]>>i)&1) { flag=true; break; }
for(int j=1;j<=scnt;j++) cnt[(dis[ dui[j] ]>>i)&1]++;//统计每个dis的这一位是0还是1 now=cnt[0]*(cnt[0]-1)/2+cnt[1]*(cnt[1]-1)/2;//组合的方式记得考虑/2!!!
now%=mod;
if(flag) {
if(r>=1) now*=fp[r-1],now%=mod;
now*=fp[i],now%=mod;
tot+=now; tot%=mod;
} now=cnt[0]*cnt[1]; now%=mod;
if(flag) { if(r>=1) now*=fp[r-1],now%=mod; }
else now*=fp[r],now%=mod;
now*=fp[i],now%=mod;
tot+=now; tot%=mod;
}
return tot;
} inline void work(){
n=getint(); m=getint(); int x,y,lim=max(n,m)*2; LL z;
for(int i=1;i<=m;i++) { x=getint(); y=getint(); z=getlong(); link(x,y,z); link(y,x,z); }
fp[0]=1; for(int i=1;i<=lim;i++) fp[i]=fp[i-1]*2,fp[i]%=mod;//预处理2的整数幂
memset(dis,-1,sizeof(dis));
for(int i=1;i<=n;i++) {
if(vis[i]) continue;
scnt=0; cir_cnt=0;
dfs(i,0,0);
ans+=calc();
ans%=mod;
}
printf("%I64d",ans);
} int main()
{
work();
return 0;
}

  

codeforces724G Xor-matic Number of the Graph的更多相关文章

  1. Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS

    G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组 ...

  2. CF 724 G. Xor-matic Number of the Graph

    G. Xor-matic Number of the Graph 链接 题意: 给定一个无向图,一个interesting的三元环(u,v,s)满足,从u到v的路径上的异或和等于s,三元环的权值为s, ...

  3. Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) G - Xor-matic Number of the Graph 线性基好题

    G - Xor-matic Number of the Graph 上一道题的加强版本,对于每个联通块需要按位算贡献. #include<bits/stdc++.h> #define LL ...

  4. CodeForces - 724G:Xor-matic Number of the Graph

    两点之间的任意路径都可表示为  随便某一条路径xor任何多个环, 然后可以用线性基来做,这样不会重复的, 另外必须一位一位的处理,xor是不满足结合律的 #include<cstdio> ...

  5. 200. Number of Islands (Graph)

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  6. Codeforces.724G.Xor-matic Number of the Graph(线性基)

    题目链接 \(Description\) 给定一张带边权无向图.若存在u->v的一条路径使得经过边的边权异或和为s(边权计算多次),则称(u,v,s)为interesting triple(注意 ...

  7. CF724G Xor-matic Number of the Graph(线性基+组合数)

    题目描述 给你一个无向图,有n个顶点和m条边,每条边上都有一个非负权值. 我们称一个三元组(u,v,s)是有趣的,当且仅当对于u,v,有一条从u到v的路径(可以经过相同的点和边多次),其路径上的权值异 ...

  8. 「CF724G」Xor-matic Number of the Graph「线性基」

    题意 求所有点对\(u,v\),\(u\)到\(v\)所有不同的异或路径的异或值之和,对\(10^9+7\)取模 题解 求出一个dfs树,那么\(u\)到\(v\)的路径一定是树上路径异或一些环.这些 ...

  9. CF724G 【Xor-matic Number of the Graph】

    题目就不翻译了吧,应该写的很清楚了... 首先 \(,\) 不懂线性基的可以戳这里.知道了线性基\(,\) 但是从来没有写过线性基和图论相结合的\(,\) 可以戳这里. 好\(,\) 点完了这些前置技 ...

随机推荐

  1. apache自带压力测试工具ab的使用及解析

    当你搭建了apache服务器并在上面部署了web网站,在网站运行前,为了使apache服务器的性能得到更好的应用,我们可以先对其进行压力测试.进行压力测试其实非常简单,我们也不用再额外下载安装什么测试 ...

  2. Test Scenarios for image upload functionality (also applicable for other file upload functionality)

    1 check for uploaded image path2 check image upload and change functionality3 check image upload fun ...

  3. 如何判断使用的是Lodop还是C-Lodop

    Lodop和C-Lodop混合部署的时候,LodopFuncs.js里面有自动判断当前浏览器使用什么,支持np插件的就会使用Lodop,不支持插件方式的会使用C-Lodop,可以通过预览窗口左上角图标 ...

  4. appium框架感悟

    个人觉得 所谓框架 最终结果就是对存放的元素进行处理 从底层获取数据 往上层传输数据过程中 对其一步一步的封装 由繁到简 再由繁至简

  5. BZOJ1042 HAOI2008硬币购物(任意模数NTT+多项式求逆+生成函数/容斥原理+动态规划)

    第一眼生成函数.四个等比数列形式的多项式相乘,可以化成四个分式.其中分母部分是固定的,可以多项式求逆预处理出来.而分子部分由于项数很少,询问时2^4算一下贡献就好了.这个思路比较直观.只是常数巨大,以 ...

  6. day11 filter函数

    场景模拟:我想判断某个列表里面的某个元素怎么怎么样 基础方法,如果需要判断多次则重复代码 ret = [] move_peole = ["alex","sb_wupeiq ...

  7. Java 入门进阶

    Java 入门进阶 發表於 2015-04-16 http://xielong.me/2015/04/16/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%B7%A5%E7%A8%8B% ...

  8. [luogu2522][bzoj2301][HAOI2011]Problem b【莫比乌斯反演】

    传送门:https://www.luogu.org/problemnew/show/P2522 题目描述 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y ...

  9. DataFrame 数据去重

    df.head() >>> Price Seqno Symbol time 0 1623.0 0.0 APPL 1473411962 1 1623.0 0.0 APPL 147341 ...

  10. 【POJ1187】陨石的秘密

    题目大意: 定义一个串:只含有 '( )','[ ]','{ }',3种(6个)字符. 定义 SS 串: 空串是SS表达式. 若A是SS表达式,且A串中不含有中括号和大括号,则(A)是SS表达式. 若 ...