codeforces724G Xor-matic Number of the Graph
本文版权归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的更多相关文章
- Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS
G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组 ...
- CF 724 G. Xor-matic Number of the Graph
G. Xor-matic Number of the Graph 链接 题意: 给定一个无向图,一个interesting的三元环(u,v,s)满足,从u到v的路径上的异或和等于s,三元环的权值为s, ...
- 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 ...
- CodeForces - 724G:Xor-matic Number of the Graph
两点之间的任意路径都可表示为 随便某一条路径xor任何多个环, 然后可以用线性基来做,这样不会重复的, 另外必须一位一位的处理,xor是不满足结合律的 #include<cstdio> ...
- 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 ...
- Codeforces.724G.Xor-matic Number of the Graph(线性基)
题目链接 \(Description\) 给定一张带边权无向图.若存在u->v的一条路径使得经过边的边权异或和为s(边权计算多次),则称(u,v,s)为interesting triple(注意 ...
- CF724G Xor-matic Number of the Graph(线性基+组合数)
题目描述 给你一个无向图,有n个顶点和m条边,每条边上都有一个非负权值. 我们称一个三元组(u,v,s)是有趣的,当且仅当对于u,v,有一条从u到v的路径(可以经过相同的点和边多次),其路径上的权值异 ...
- 「CF724G」Xor-matic Number of the Graph「线性基」
题意 求所有点对\(u,v\),\(u\)到\(v\)所有不同的异或路径的异或值之和,对\(10^9+7\)取模 题解 求出一个dfs树,那么\(u\)到\(v\)的路径一定是树上路径异或一些环.这些 ...
- CF724G 【Xor-matic Number of the Graph】
题目就不翻译了吧,应该写的很清楚了... 首先 \(,\) 不懂线性基的可以戳这里.知道了线性基\(,\) 但是从来没有写过线性基和图论相结合的\(,\) 可以戳这里. 好\(,\) 点完了这些前置技 ...
随机推荐
- U9财务体系
- MySQL中条件放在where后面与放在on后面的区别
假设有两种表:test_on_position表和address表,address表存放地址,test_on_position存放会员及其常用的地址,数据如下: address表: test_on_p ...
- python之tkinter使用-文件系统遍历
# tkinter:文件系统遍历 import tkinter as tk, os from time import sleep class DirList(object): def __init__ ...
- hdu 6394 Tree (2018 Multi-University Training Contest 7 1009) (树分块+倍增)
链接: http://acm.hdu.edu.cn/showproblem.php?pid=6394 思路:用dfs序处理下树,在用分块,我们只需要维护当前这个点要跳出这个块需要的步数和他跳出这个块去 ...
- 洛谷P2480 [SDOI2010]古代猪文(费马小定理,卢卡斯定理,中国剩余定理,线性筛)
洛谷题目传送门 蒟蒻惊叹于一道小小的数论题竟能涉及这么多知识点!不过,掌握了这些知识点,拿下这道题也并非难事. 题意一行就能写下来: 给定\(N,G\),求\(G^{\sum \limits _{d| ...
- 【BZOJ2142】礼物(拓展卢卡斯定理)
[BZOJ2142]礼物(拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 显然如果\(\sum w_i>n\)无解. 否则答案就是:\(\displaystyle \prod_{i=1}^m{n- ...
- SharePoint 错误集
1. Delete a site collection · Run command : Remove-SPSite –Identity http://ent132.sharepoint.hp.com/ ...
- uoj【UNR #3】To Do Tree 【贪心】
题目链接 uojUNR3B 题解 如果不输出方案,是有一个经典的三分做法的 但是要输出方案也是可以贪心的 设\(d[i]\)为\(i\)节点到最深的儿子的距离 贪心选择\(d[i]\)大的即可 #in ...
- HDU 3605 Escape (网络流,最大流,位运算压缩)
HDU 3605 Escape (网络流,最大流,位运算压缩) Description 2012 If this is the end of the world how to do? I do not ...
- P1382 楼房 set用法小结
这个sb题目,剧毒... STL大法好 首先,我准备用经典的线段树优化扫描线来做.之前的矩形周长把我困了数天导致我胸有成竹. 然后,敲代码半小时,调试半个月......这个,sb,怎么改都是0分+2个 ...