这是一个三元环计数的裸题,只是多了一个颜色的区分和权值的计算罢了。

有一种根号分治的做法(by gxz)

这种复杂度的证明特别显然,思路非常简单,不过带一个log,可以用unordered_map或者bitset之类的$O(1)$判连通。


我的做法的话采用了一个比较奇怪的思路?每条边,度数大的点向度数小的点连有向边,然后枚举第一层点,枚举出发到达的第二层点,这两层加起来复杂度总的是$O(m)$,然后从第二层点枚举出边到第三层点,看第三层点和第一层点是不是连通的,这个复杂度我好像在这里写过证明,就不贴了。注意一下重边的话,只要把相同颜色的权值累加起来做乘法就行(line47)。

理论上说是根号的做法,但是我跑了9s???

人家带一个log的都比我跑的快一倍,莫非我复杂度是假的?

不清楚,如果有神仙指导不胜感激。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;else if(c=='R'||c=='G'||c=='B'){x=c;break;}
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=1e5+,P=1e9+;
struct thxorz{
int head[N],w[N<<],nxt[N<<],to[N<<],typ[N<<],tot;
thxorz(){tot=;}
inline void add(int x,int y,int z,int ty){to[++tot]=y,nxt[tot]=head[x],head[x]=tot,w[tot]=z,typ[tot]=ty;}
}G,E;
inline void add(int&a,int b){a+=b;a>=P&&(a-=P);}
inline int mod(int a){return a>=P?a-=P:a;}
int deg[N],vis[N][],val[N][];
int n,m,ans;
inline int cmp(int a,int b){return deg[a]==deg[b]?a<b:deg[a]<deg[b];} int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n),read(m);
for(register int i=;i<=m<<;i+=)++deg[read(E.to[i])],++deg[read(E.to[i+])],read(E.w[i]),read(E.typ[i]);
for(register int i=;i<=m<<;i+=){
if(!cmp(E.to[i],E.to[i+]))G.add(E.to[i+],E.to[i],E.w[i],E.typ[i]=='R'?:(E.typ[i]=='G'?:));
else G.add(E.to[i],E.to[i+],E.w[i],E.typ[i]=='R'?:(E.typ[i]=='G'?:));
}
for(register int x=;x<=n;++x){//x
#define y G.to[j]
#define t G.typ[j]
for(register int j=G.head[x];j;j=G.nxt[j]){
if(vis[y][t]^x)vis[y][t]=x,val[y][t]=G.w[j];
else add(val[y][t],G.w[j]);
}
#define z G.to[k]
#define tt G.typ[k]
for(register int j=G.head[x];j;j=G.nxt[j]){//y
for(register int k=G.head[y];k;k=G.nxt[k])if(t^tt){//z
if(vis[z][-t-tt]==x)add(ans,G.w[j]*1ll*G.w[k]%P*val[z][-t-tt]%P);
}
}
}
printf("%d\n",ans);
return ;
}

总结:这相当于是把原来$O(mn)$的做法尝试通过连边、度数等减少枚举。。

BZOJ5206 [Jsoi2017]原力[根号分治]的更多相关文章

  1. 【bzoj5206】[Jsoi2017]原力 根号分治+STL-map

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

  2. BZOJ5206: [Jsoi2017]原力

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

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

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

  4. bzoj 5206 [Jsoi2017]原力

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

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

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

  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. Codeforces 1039D You Are Given a Tree [根号分治,整体二分,贪心]

    洛谷 Codeforces 根号分治真是妙啊. 思路 考虑对于单独的一个\(k\)如何计算答案. 与"赛道修建"非常相似,但那题要求边,这题要求点,所以更加简单. 在每一个点贪心地 ...

  8. BZOJ.4320.[ShangHai2006]Homework(根号分治 分块)

    BZOJ \(\mathbb{mod}\)一个数\(y\)的最小值,可以考虑枚举剩余系,也就是枚举区间\([0,y),[y,2y),[2y,3y)...\)中的最小值(求后缀最小值也一样)更新答案,复 ...

  9. CF1039E Summer Oenothera Exhibition 贪心、根号分治、倍增、ST表

    传送门 感谢这一篇博客的指导(Orzwxh) $PS$:默认数组下标为$1$到$N$ 首先很明显的贪心:每一次都选择尽可能长的区间 不妨设$d_i$表示在取当前$K$的情况下,左端点为$i$的所有满足 ...

随机推荐

  1. 44.python排序算法(冒泡+选择)

    一,冒泡排序: 是一种简单的排序算法.它重复地遍历要排序的数列,一次比较两个,如果他们的排序错误就把他们交换过来. 冒泡排序是稳定的(所谓稳定性就是两个相同的元素不会交换位置) 冒泡排序算法的运作如下 ...

  2. win10配置Keras及GPU环境

    今天搭建了Keras深度学习的环境 详细记录一下 安装Anaconda3 Anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项. Anac ...

  3. Guava 工具类之joiner的使用

    joiner主要用于对字符串的连接,也可用于对map中key value的连接 public class JoinerTest { private static final List<Strin ...

  4. Docker daemon.json 的配置项目合集

    这几天看了一点docker相关的东西, 在学习中: 看了下园友的blog 感觉很好 这里 学习一下. https://www.cnblogs.com/pzk7788/p/10180197.html 其 ...

  5. oracle中表记录被另一个用户锁住

    应用场景 在查询oracle表时,提示表记录被另一个用户锁住了 有可能是在使用了pl/sql工具后修改某个表记录时,加锁,或者发生故障异常退出,下次登录进去修改不了 查询锁 --查看数据库的锁的来源. ...

  6. 记搜狗一次不成功的Python后端面试经历

    面试搜狗Python后端结束快一个月了,终于有时间来做一个简单的总结了. 简介:工作不久,基础后端岗位,一面结束,失败. 先做了几个笔试题,面试开始会根据笔试题问一些内容.下面将整理一下还能想起来的内 ...

  7. Eureka 服务中心

    old                                                                                           使用Eure ...

  8. php常用扩展有哪些

    bcmath(精确数值处理) bz2 calendar Core ctype curl date dom ereg exif fileinfo filter ftp gettext hash icon ...

  9. Python爬虫—requests库get和post方法使用

    目录 Python爬虫-requests库get和post方法使用 1. 安装requests库 2.requests.get()方法使用 3.requests.post()方法使用-构造formda ...

  10. C++反汇编第二讲,反汇编中识别虚表指针,以及指向的虚函数地址

    讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当然也可以看原博客链接: http://blog.csdn.net ...