[JSOI2017]原力(分块+map(hash))
2018-04-01 19:01
267 查看
题目描述
一个原力网络可以看成是一个可能存在重边但没有自环的无向图。每条边有一种属性和一个权值。属性可能是R、G、B三种当中的一种,代表这条边上 原力的类型。权值是一个正整数,代表这条边上的原力强度。原力技术的核心在于将R、G、B三种不同的原力融合在一起产生单一的、便于利用的原力。为了评估 一个能源网络,JYY需要找到所有满足要求的三元环(首尾相接的三条边),其中R、G、B三种边各一条。一个三元环产生的能量是其中三条边的权值之积。 现在对于给出的原力网络,JYY想知道这个网络的总能量是多少。网络的总能量是所有满足要求三元环的能量之和。输入
第一行包含两个正整数N、M。表示原力网络的总顶点个数和总边数。 接下来M行,每行包含三个正整数ui,vi,wi和一个字符ci。 表示编号ui和vi的顶点之间存在属性为ci权值为wi的一条边。 N≤50,000,M≤100,000,1≤?Wi≤10^6输出
输出一行一个整数,表示这个原力网络的总能量模10^9+7的值
样例输入
4 6
1 2 2 R
2 4 3 G
4 3 5 R
3 1 7 G
1 4 11 B
2 3 13 B样例输出
828
惯例的分块(第一次做实在想不到但这是一个套路,不仅在图上,在数学动规等处也有应用),度数比$\sqrt n$大的点成为大点,其余称为小点。
只有大点的三元环直接暴力即可,然后对于每个小点,枚举它的两条出边hash判断。枚举第一条边的复杂度与边数同阶,枚举第二条边的复杂度为边数成小点的度数,即不超过$O(m\sqrt n)$。
#include<map> #include<cmath> #include<cstdio> #define rep(i,l,r) for (int i=l; i<=r; i++) typedef long long ll; using namespace std; const int N=50100,mod=1000000007; struct data{ int x,y,z; data() {} data(int a,int b,int c) {x=a,y=b,z=c;} bool operator<(const data &a)const {return x == a.x ? y == a.y ? z < a.z : y < a.y : x < a.x;} }; map<data,ll> mp; int n,m,si,x,y,z,t,head ,to[N << 2],val[N << 2],opt[N << 2],next[N << 2],cnt,d ,id[350],tot; char str[5]; void add(int x,int y,int v,int c){ to[++cnt]=y,val[cnt]=v,opt[cnt]=c,next[cnt]=head[x],head[x]=cnt; } int main(){ ll ans=0; scanf("%d%d",&n,&m),si=(int)sqrt(m); rep(i,1,m){ scanf("%d%d%d%s",&x,&y,&z,str); t=(str[0] == 'R' ? 1 : str[0] == 'G' ? 2 : 3); add(x,y,z,t),add(y,x,z,t),d[x] ++,d[y] ++ ; (mp[data(x,y,t)] += z) %= mod,(mp[data(y,x,t)] += z) %= mod; } rep(i,1,n) if(d[i] >= si) id[++tot]=i; rep(i,1,tot) rep(j,1,tot) rep(k,1,tot) ans=(ans+mp[data(id[i],id[j],1)]*mp[data(id[i],id[k],2)]%mod*mp[data(id[j],id[k],3)])%mod; rep(i,1,n) if(d[i] < si) for(int j=head[i] ; j ; j=next[j]) if(d[to[j]] >= si || to[j] > i) for(int k=next[j]; k; k=next[k]) if(opt[k]!=opt[j] && (d[to[k]]>=si || to[k]>i)) ans=(ans+mp[data(to[j],to[k],6-opt[j]-opt[k])]*val[j]%mod*val[k])%mod; printf("%lld\n",ans); return 0; }
相关文章推荐
- 【bzoj5206】[Jsoi2017]原力 根号分治+STL-map
- [三元环] BZOJ5206: [Jsoi2017]原力
- [分块 随机Hash] Romanian IOI 2017 Selection #6 Jolteon
- BZOJ5206 [Jsoi2017]原力
- [JSOI2017]原力
- [ACE] ACE_Hash_Map_With_Allocator性能测试
- 【学习笔记】关于STL中的map和hash_map
- gold_hash_map vs google sparse map by google's time_hash_map.cc
- 三 关联式容器(五)hash_map与hash_multimap
- hash_map的hash函数
- hash_map
- 详细解说STL hash_map系列
- c++中关于hash_map自定义equal function和hash function
- C++ hash_map 与 Java HashMap 的区别
- c++hash_map详解
- STL容器:set/map/multiset/multimap 与hash_set/hash_map/hash_multiset/hash_multimap
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 Barty's Computer(暴力+hash)
- 集训笔记1-set,map,hash,字符hash
- VC的hash_map和GCC hash_map用法区别
- BZOJ1014 [JSOI2008]火星人prefix(Splay+字符串Hash)