LINK:原力

一张无向图 这道题统计三元环的价值和。有重边但是无自环。

我曾经写过三元环计数 这个和那个题差不太多。

不过有很多额外操作 对于重边问题 我们把所有颜色相同的重边缩在一起 这样的话我们就可以针对点来运算了。

不过这样做开邻接表就很困难了 (直接map爽...

接下来是正规的三元环计数了 我们考虑重新建图 度数小的连向度数大的 度数相等的由编号小的连向编号大的。

可以暴力枚举每个点 标记所到达的点(暴力枚举合并过后的边 再枚举一条边去统计答案 这样就完事了。

可以观察一下复杂度 外层暴力枚举是O(m)的 内层我们考虑再枚举一条边 度数小于sqrt(m)的点复杂度为sqrt(m)

大于sqrt(m)的因为连向的只有>sqrt(m)的所以复杂度还是sqrt(m).

那其实内层均摊msqrt(m) 外层枚举好像跟内层复杂度没有联系 所以总复杂度 msqrt(m).

这里简述另外一种分治法:(这种分治法更容易分析复杂度。

对于三个点度数大于sqrt(m)的 我们可以直接暴力枚举三个点 复杂度显然msqrt(m).

反之 枚举一个点 其两条出边来判断 不重不漏的话我们规定编号最小的点能够枚举到这个环即可。

可以看出后者复杂度 msqrt(m).

对于这两种分治法 一般叫做根号分治 非常行之有效的方法。

运用第一种方法 我T的不省人事。

const int MAXN=100010;
int n,m,len;
struct wy{int x,y;}t[MAXN];
int ru[MAXN];
map<pii,int>H[3];
char a[10];
int lin[MAXN],ver[MAXN],nex[MAXN];
inline void add(int x,int y){ver[++len]=y;nex[len]=lin[x];lin[x]=len;}
int main()
{
//freopen("1.in","r",stdin);
gt(n);gt(m);
rep(1,m,i)
{
int x,y,z;
gt(x);gt(y);gt(z);gc(a);
int w=a[1]=='R'?0:a[1]=='G'?1:2;
if(x>y)swap(x,y);++ru[x];++ru[y];
H[w][mk(x,y)]=(H[w][mk(x,y)]+z)%mod;
t[i]=(wy){x,y};
}
for(int i=1;i<=m;++i)
{
int x=t[i].x,y=t[i].y;
if(ru[x]==ru[y]||ru[x]<ru[y])add(x,y);
else add(y,x);
}
ll ans=0;
for(int i=1;i<=n;++i)
{
for(int j=lin[i];j;j=nex[j])
{
int tn=ver[j];
for(int k=lin[tn];k;k=nex[k])
{
int w1=ver[k];
ans=(ans+(ll)H[1][mk(min(i,tn),max(i,tn))]*H[2][mk(min(tn,w1),max(tn,w1))]*H[0][mk(min(i,w1),max(i,w1))])%mod;
ans=(ans+(ll)H[1][mk(min(i,tn),max(i,tn))]*H[0][mk(min(tn,w1),max(tn,w1))]*H[2][mk(min(i,w1),max(i,w1))])%mod;
ans=(ans+(ll)H[2][mk(min(i,tn),max(i,tn))]*H[1][mk(min(tn,w1),max(tn,w1))]*H[0][mk(min(i,w1),max(i,w1))])%mod;
ans=(ans+(ll)H[2][mk(min(i,tn),max(i,tn))]*H[0][mk(min(tn,w1),max(tn,w1))]*H[1][mk(min(i,w1),max(i,w1))])%mod;
ans=(ans+(ll)H[0][mk(min(i,tn),max(i,tn))]*H[1][mk(min(tn,w1),max(tn,w1))]*H[2][mk(min(i,w1),max(i,w1))])%mod;
ans=(ans+(ll)H[0][mk(min(i,tn),max(i,tn))]*H[2][mk(min(tn,w1),max(tn,w1))]*H[1][mk(min(i,w1),max(i,w1))])%mod;
}
}
}
putl(ans);
//cout<<H[1][mk(min(1,2),max(1,2))]<<endl;
return 0;
} const int MAXN=100010,M=10000007;
int n,m,len,len1;
struct wy{int x,y,z,e;}t[MAXN];
int ru[MAXN];char a[10];
struct jl
{
int x,y,w;
jl(){x=y=w=0;};
jl(int a,int b,int c){x=a;y=b;w=c;}
inline int friend operator ==(jl a,jl b){return a.x==b.x&&a.y==b.y&&a.w==b.w;}
}s[M],s1;
int lin[MAXN],ver[MAXN],nex[MAXN],e[MAXN],e1[MAXN];
inline void add(int x,int y,int z,int z1){ver[++len]=y;nex[len]=lin[x];lin[x]=len;e[len]=z;e1[len]=z1;}
int lin1[M],nex1[M],v[M];
inline int ha1(int x,int y,int w){return ((x*P+w)%M*P+y+w*y%M*x)*P%M;}
inline int find(int x,int y,int w,int z)
{
s1=jl(x,y,w);
int xx=ha1(x,y,w);
for(int i=lin1[xx];i;i=nex1[i])
if(s1==s[i]){v[i]=(v[i]+z)%mod;return v[i];}
return 0;
}
inline void ha(int x,int y,int w,int z)
{
if(find(x,y,w,z))return;
int ww=((x*P+w)%M*P+y+w*y%M*x)*P%M;
s[++len1]=s1;
nex1[len1]=lin1[ww];
lin1[ww]=len1;
v[len1]=z;
}
int main()
{
freopen("1.in","r",stdin);
gt(n);gt(m);
rep(1,m,i)
{
int x,y,z;
gt(x);gt(y);gt(z);gc(a);
int w=a[1]=='R'?0:a[1]=='G'?1:2;
if(x>y)swap(x,y);++ru[x];++ru[y];
t[i]=(wy){x,y,w,z};ha(x,y,w,z);
}
for(int i=1;i<=m;++i)
{
int x=t[i].x,y=t[i].y,w=t[i].z,z=t[i].e;
if(ru[x]==ru[y]||ru[x]<ru[y])add(x,y,w,z);
else add(y,x,w,z);
}
ll ans=0;
for(int i=1;i<=n;++i)
{
for(int j=lin[i];j;j=nex[j])
{
for(int k=lin[ver[j]];k;k=nex[k])
{
int w1=ver[k];
if(e[k]==e[j])continue;
int w2=i;if(w1>w2)swap(w1,w2);
int ww=find(w1,w2,3-e[j]-e[k],0);
ans=(ans+(ll)e1[j]*e1[k]%mod*ww)%mod;
}
}
}
putl(ans);
return 0;
} const int MAXN=50010;
struct wy
{
int x,y,z;
wy(){x=y=z=0;}
wy(int a,int b,int c){x=a;y=b;z=c;}
bool operator<(const wy a)const{return x==a.x?y==a.y?z<a.z:y<a.y:x<a.x;}
};
map<wy,int>H;
int lin[MAXN],ver[MAXN<<2],nex[MAXN<<2],e[MAXN<<2],e1[MAXN<<2];
int n,m,si,len,cnt,d[MAXN],id[MAXN],tot;
char a[5];
inline void add(int x,int y,int z,int z1)
{
ver[++len]=y;nex[len]=lin[x];lin[x]=len;e[len]=z;e1[len]=z1;
}
int main()
{
freopen("1.in","r",stdin);
gt(n);gt(m);si=(int)sqrt(m*1.0);
ll ans=0;
rep(1,m,i)
{
int x,y,z;
gt(x);gt(y);gt(z);gc(a);
int w=a[1]=='R'?1:a[1]=='G'?2:3;
add(x,y,z,w);add(y,x,z,w);
++d[x];++d[y];
(H[wy(x,y,w)]+=z)%=mod;(H[wy(y,x,w)]+=z)%=mod;
}
rep(1,n,i)if(d[i]>=si)id[++tot]=i;
rep(1,tot,i)rep(1,tot,j)rep(1,tot,k)
ans=(ans+(ll)H[wy(id[i],id[j],1)]*H[wy(id[j],id[k],2)]%mod*H[wy(id[i],id[k],3)])%mod;
rep(1,n,i)
{
if(d[i]<si)
for(int j=lin[i];j;j=nex[j])
{
if(d[ver[j]]>=si||ver[j]>i)
for(int k=nex[j];k;k=nex[k])
if(e1[j]!=e1[k]&&(d[ver[k]]>=si||ver[k]>i))
ans=(ans+(ll)H[wy(ver[j],ver[k],6-e1[j]-e1[k])]*e[j]%mod*e[k])%mod;
}
}
putl(ans);return 0;
}

上面 是两个版本的 第一种方法外面分析复杂度是正确的 可就是跑的过于慢了 加上hash也是如此。

不得不采用第一种方法 我们把大于sqrt的抽出来单独跑 考虑不重不漏 显然一个三元环我们以唯一方向寻找 那么就不会重复。

考虑小的点 显然我么小的点枚举边 外层O(m) 内层<sqrt(m) 注意不重不漏 那么我们定义一个环由编号最小的节点开始即可。

代码也放上面好了.

郁闷的是 为什么第一种方法一直T 我也不知道为啥。

bzoj 5206 [Jsoi2017]原力的更多相关文章

  1. BZOJ5206: [Jsoi2017]原力

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

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

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

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

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

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

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

  5. [JSOI2017]原力

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

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

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

  7. 报名 | 蚂蚁金服ATEC科技大会 · 上海:数字金融新原力

    小蚂蚁说: 2019年1月4日,蚂蚁金服ATEC城市峰会将以“数字金融新原力(The New Force of Digital Finance)”为主题,在中国上海举办.蚂蚁金服ATEC(Ant Te ...

  8. ​第3届云原生技术实践峰会(CNBPS 2020)重磅开启,“原”力蓄势待发!

    CNBPS 2020将在11月19-21日全新启动!作为国内最有影响力的云原生盛会之一,云原生技术实践峰会(CNBPS)至今已举办三届. 在2019年的CNBPS上,灵雀云CTO陈恺喊出"云 ...

  9. CSDN 原力(声望,影响力) -- 设计草案

    目标 CSDN 希望成为开发者学习,成长和成就的平台.我们已经有很多功能来支持开发者的职业成长了, 如何衡量成就呢?我们希望用 原力 (以前也叫 影响力,声望) 来体现用户的成就, 并希望用原力来帮助 ...

随机推荐

  1. vx小程序(1)

    一.程序配置 app.json 1. pages字段——用于描述当前小程序的页面路径. 2.window字段——定义小程序所有页面的顶部背景颜色,文字颜色等. 注意:可以在pages/logs目录下的 ...

  2. 状压DP之互不侵犯

    题目描述 这里 在\(N*N\) 的棋盘里面放\(k\)个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入格式 只有 ...

  3. 确定比赛名次 UDU-1285 + 逃生 UDU 4857 拓扑排序(找不同)

    确定比赛名次 题目大意 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得 ...

  4. 基于图嵌入的高斯混合变分自编码器的深度聚类(Deep Clustering by Gaussian Mixture Variational Autoencoders with Graph Embedding, DGG)

    基于图嵌入的高斯混合变分自编码器的深度聚类 Deep Clustering by Gaussian Mixture Variational Autoencoders with Graph Embedd ...

  5. python入门008

    目录 一.for循环 作用:for循环是因为在循环取值(即遍历值)时for循环比while循环的使用更为简洁 1.for循环语法: 2.应用案例: 注意:break 与 continue也可以用于fo ...

  6. Centos7之LNMP环境编译安装

    Centos7之LNMP环境编译安装 一.系统环境准备 注:安装时间过长,只做参考!!!1.系统信息 [root@localhost ~]# uname -r 3.10.0-957.el7.x86_6 ...

  7. 同一台机器oralce11g和12c公用一个监听器监听多个端口

    启动数据库服务 (这里还没有启动监听器) 如上图OracleServiceORCL为11g的服务,服务名为orcl,OracleServiceWX为12c的服务名,服务名为wx,两个服务均已正常启动, ...

  8. Oracle数据泵详解

    一.EXPDP和IMPDP使用说明 Oracle Database 10g引入了最新的数据泵(Data Dump)技术,数据泵导出导入(EXPDP和IMPDP)的作用 1)实现逻辑备份和逻辑恢复. 2 ...

  9. 什么是viewstate,能否禁用?是否所用控件都可以禁用

    viewstate用于在两次postback之间保持状态的一种机制禁用viewstate将不能在回发之间保存状态 当控件状态无关使用viewstate将造成性能问题时需要禁用viewstate Vie ...

  10. jspang 做个那个pos系统--学习笔记

    /为什么不能使用Object.assign() //使用Object.assign之后数据会发生改变,但是试图没有跟新 <template> <div class="pos ...