题目描述

一个原力网络可以看成是一个可能存在重边但没有自环的无向图。每条边有一种属性和一个权值。属性可能是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


题解

根号分治+STL-map

看到这种根本没法写出什么玄学数据结构之类的,大概率就是根号分治了。

对于本题,由于边数只有 $m$ ,因此度数大于等于 $\sqrt m$ 的点只有 $O(\sqrt m)$ 个,我们称这样的点为大点,度数小于 $\sqrt m$ 的称为小点。

那么对于一个三元环:

如果三个点都是大点:这种情况下我们暴力枚举三个大点,求出是否有满足条件的三元环并加入到答案中即可。时间复杂度为 $O((\sqrt m)^3)=O(m\sqrt m)$ ;

如果三个点中有小点:这种情况下我们枚举每个小点和它的两条出边,判断这三个点是否有满足条件的三元环。此时,枚举第一条出边相当于枚举图中所有边,第二条出边是度数复杂度,而度数小于 $\sqrt m$ ,因此复杂度也是 $O(m\sqrt m)$ 的。注意这个过程需要保证不重不漏,因此只考虑枚举点为这三个点中编号最小的小点的答案。

那么如何判断是否有满足条件的三元环呢?我偷懒了使用STL-map判断两点之间有没有某颜色的边,复杂度上会多一个log。

时间复杂度 $O(m\sqrt m\log m)$ ,实际上跑得挺快的 然而在bz上还是倒数第一...

#include <map>
#include <cmath>
#include <cstdio>
#define N 50010
#define mod 1000000007
using namespace std;
typedef long long ll;
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 head[N] , to[N << 2] , val[N << 2] , opt[N << 2] , next[N << 2] , cnt , d[N] , id[350] , tot;
char str[5];
inline 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()
{
int n , m , si , i , j , k , x , y , z , t;
ll ans = 0;
scanf("%d%d" , &n , &m) , si = (int)sqrt(m);
for(i = 1 ; i <= m ; i ++ )
{
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;
}
for(i = 1 ; i <= n ; i ++ )
if(d[i] >= si)
id[++tot] = i;
for(i = 1 ; i <= tot ; i ++ )
for(j = 1 ; j <= tot ; j ++ )
for(k = 1 ; k <= tot ; k ++ )
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;
for(i = 1 ; i <= n ; i ++ )
if(d[i] < si)
for(j = head[i] ; j ; j = next[j])
if(d[to[j]] >= si || to[j] > i)
for(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的更多相关文章

  1. BZOJ5206 [Jsoi2017]原力[根号分治]

    这是一个三元环计数的裸题,只是多了一个颜色的区分和权值的计算罢了. 有一种根号分治的做法(by gxz) 这种复杂度的证明特别显然,思路非常简单,不过带一个log,可以用unordered_map或者 ...

  2. BZOJ5206: [Jsoi2017]原力

    BZOJ5206: [Jsoi2017]原力 https://lydsy.com/JudgeOnline/problem.php?id=5206 分析: 比较厉害的三元环问题. 设立阈值,当点的度数大 ...

  3. BZOJ5206 JSOI2017原力(三元环计数)

    首先将完全相同的边的权值累加.考虑这样一种trick:给边确定一个方向,由度数小的连向度数大的,若度数相同则由编号小的连向编号大的.这样显然会得到一个DAG.那么原图的三元环中就一定有且仅有一个点有两 ...

  4. [JSOI2017]原力(分块+map(hash))

    题目描述 一个原力网络可以看成是一个可能存在重边但没有自环的无向图.每条边有一种属性和一个权值.属性可能是R.G.B三种当中的一种,代表这条边上 原力的类型.权值是一个正整数,代表这条边上的原力强度. ...

  5. bzoj 5206 [Jsoi2017]原力

    LINK:原力 一张无向图 这道题统计三元环的价值和.有重边但是无自环. 我曾经写过三元环计数 这个和那个题差不太多. 不过有很多额外操作 对于重边问题 我们把所有颜色相同的重边缩在一起 这样的话我们 ...

  6. [JSOI2017]原力

    题目大意: 一个$n(n\le5\times10^4)$个点,$m(m\le10^5)$条边的无向图.每条边有一个边权$w_i(w_i\le10^6)$和一个附加属性$t_i(t_i\in\{R,G, ...

  7. nowcoder 79F 小H和圣诞树 换根 DP + 根号分治

    设节点个数大于 $\sqrt n$ 的颜色为关键颜色,那么可以证明关键颜色最多有 $\sqrt n$ 个.对于每个关键颜色,暴力预处理出该颜色到查询中另一个颜色的距离和. 对于不是关键颜色的询问,直接 ...

  8. (转载)STL map与Boost unordered_map的比较

    原链接:传送门 今天看到 boost::unordered_map,它与 stl::map的区别就是,stl::map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合 ...

  9. CF804D Expected diameter of a tree 树的直径 根号分治

    LINK:Expected diameter of a tree 1e5 带根号log 竟然能跑过! 容易想到每次连接两个联通快 快速求出直径 其实是 \(max(D1,D2,f_x+f_y+1)\) ...

随机推荐

  1. 20155336 2016-2017-2 《Java程序设计》第三周学习总结

    20155336 2016-2017-2 <Java程序设计>第三周学习总结 教材学习内容总结 第四章 类与对象 定义: 对象(Object):存在的具体实体,具有明确的状态和行为. 类( ...

  2. SupperSocket深入浅出(二)

    如果还没有看SuperStock深入浅出(一) ,请先看 这一章,主要说下命令是如果运行的.刚开始的时候会发现拷别人的代码命令是可以运行的,在修改的过程中突然发现命令无效了? 这里什么原因?,我先把代 ...

  3. 探寻ASP.NET MVC鲜为人知的奥秘(1):对LESS的支持

    在ASP.NET MVC3中(从那时开始),我们拥有了对js和css等文件的捆绑(Bundling)和压缩(Minification)的能力,这是ASP.NET性能优化工作的一部分. 想一下很久以前, ...

  4. Maven学习(十五)-----Maven常用命令

    一.Maven常用命令 1.1.Maven 参数 -D 传入属性参数  -P 使用pom中指定的配置  -e 显示maven运行出错的信息  -o 离线执行命令,即不去远程仓库更新包  -X 显示ma ...

  5. Windows网络通信(一):socket同步编程

    网络通信常用API 1. WSAStartup用于初始化WinSock环境 int WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData ); ...

  6. JSP整理

    JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%>结束. JSP是一种Java servlet ...

  7. Egret入门(二)--windows下环境搭建

    准备材料 安装Node.js TypeScript编辑器 HTTP服务器(可选) Chorme(可选) Egret 安装Node.js 打开www.nodejs.org 下载安装(全部next,全默认 ...

  8. JVM自动内存管理机制--读这篇就GO了

    之前看过JVM的相关知识,当时没有留下任何学习成果物,有些遗憾.这次重新复习了下,并通过博客来做下笔记(只能记录一部分,因为写博客真的很花时间),也给其他同行一些知识分享. Java自动内存管理机制包 ...

  9. 母版页 MasterPage

    母版页是一个扩展名为.master的ASP.NET文件,主要是为了应用程序创建统一的用户功能界面和样式. ContentPlaceHolder控件只能在母版页中使用,在平常的web页面使用,会发生解析 ...

  10. Kubernetes v1.10----部署kubernetes-dashboard v1.83

    Kubernetes v1.10----部署kubernetes-dashboard v1.83 1.下载 kubernetes-dashboard  yaml文件 #因为文件中的image指定的是谷 ...