[CF855G]Harry Vs Voldemort

题目大意:

一棵\(n(n\le10^5)\)个结点的树,\(q(q\le10^5)\)次操作,每次增加一条新边。每次操作后,你需要统计形如\((u,v,w)\)的三元组的数量,使得\(u,v,w\)都不相同,并存在两条分别\(u\)到\(w\)和\(v\)到\(w\)的路径,使得两条路径没有共同边。

思路:

每次加边相当于将两个顶点之间的所有边缩成了一个边双连通分量。

考虑三元组\((u,v,w)\):

  1. \(u,v,w\)均在同一个边双中;
  2. \(u,v\)中有一个在与\(w\)相同的边双中;
  3. \(u,v,w\)均在不同的边双中。

对三种情况分别讨论即可。

对于情况2,3,只需维护边双大小\(size[u]\);对于情况1,还需维护子树大小\(tsize[u]\),和\(u,v\)分布在相同(或不同)子树中的方案数。

边双缩点可以用并查集实现。

时间复杂度\(\mathcal O(n\alpha(n))\)。

源代码:

  1. #include<cstdio>
  2. #include<cctype>
  3. #include<vector>
  4. #include<numeric>
  5. inline int getint() {
  6. register char ch;
  7. while(!isdigit(ch=getchar()));
  8. register int x=ch^'0';
  9. while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
  10. return x;
  11. }
  12. typedef long long int64;
  13. const int N=1e5+1;
  14. std::vector<int> e[N];
  15. inline void add_edge(const int &u,const int &v) {
  16. e[u].push_back(v);
  17. e[v].push_back(u);
  18. }
  19. int64 ans,val[N],tmp[N];
  20. int n,par[N],dep[N],size[N],tsize[N];
  21. struct DisjointSet {
  22. int anc[N];
  23. void reset(const int &n) {
  24. std::iota(&anc[1],&anc[n]+1,1);
  25. }
  26. int find(const int &x) {
  27. return x==anc[x]?x:anc[x]=find(anc[x]);
  28. }
  29. void merge(const int &x,const int &y) {
  30. anc[find(x)]=find(y);
  31. }
  32. bool same(const int &x,const int &y) {
  33. return find(x)==find(y);
  34. }
  35. };
  36. DisjointSet djs;
  37. void dfs(const int &x,const int &par) {
  38. ::par[x]=par;
  39. dep[x]=dep[par]+1;
  40. size[x]=tsize[x]=1;
  41. for(int y:e[x]) {
  42. if(y==par) continue;
  43. dfs(y,x);
  44. tsize[x]+=tsize[y];
  45. }
  46. }
  47. int64 calc(const int &x) {
  48. int64 ans=0;
  49. ans+=1ll*size[x]*(size[x]-1)*(size[x]-2);//XXX
  50. ans+=2ll*size[x]*(size[x]-1)*(n-size[x]);//XX-Y & Y-XX
  51. ans+=1ll*(n-size[x])*(n-size[x])*size[x];
  52. for(int y:e[x]) {//Y-X-Z & Z-X-Y
  53. if(djs.same(x,y)) continue;
  54. const int z=djs.find(y);
  55. const int sz=y==par[x]?n-tsize[x]:tsize[z];
  56. ans-=1ll*sz*sz*size[x];
  57. tmp[x]+=1ll*sz*sz;
  58. }
  59. return val[x]=ans;
  60. }
  61. int64 calc2(const int &x) {
  62. int64 ans=0;
  63. ans+=1ll*size[x]*(size[x]-1)*(size[x]-2);//XXX
  64. ans+=2ll*size[x]*(size[x]-1)*(n-size[x]);//XX-Y & Y-XX
  65. ans+=1ll*(n-size[x])*(n-size[x])*size[x];//Y-X-Z & Z-X-Y
  66. ans-=tmp[x]*size[x];
  67. return val[x]=ans;
  68. }
  69. void merge(int u,int v) {
  70. u=djs.find(u);
  71. v=djs.find(v);
  72. while(u!=v) {
  73. if(dep[u]<dep[v]) std::swap(u,v);
  74. const int w=djs.find(par[u]);
  75. tmp[w]-=1ll*tsize[u]*tsize[u];
  76. tmp[w]+=tmp[u]-1ll*(n-tsize[u])*(n-tsize[u]);
  77. ans-=val[u];
  78. size[w]+=size[u];
  79. djs.merge(u,w);
  80. u=w;
  81. }
  82. ans-=val[u];
  83. ans+=calc2(u);
  84. }
  85. int main() {
  86. n=getint();
  87. for(register int i=1;i<n;i++) {
  88. add_edge(getint(),getint());
  89. }
  90. djs.reset(n);
  91. dfs(1,0);
  92. for(register int x=1;x<=n;x++) {
  93. ans+=calc(x);
  94. }
  95. printf("%lld\n",ans);
  96. const int q=getint();
  97. for(register int i=0;i<q;i++) {
  98. merge(getint(),getint());
  99. printf("%lld\n",ans);
  100. }
  101. return 0;
  102. }

[CF855G]Harry Vs Voldemort的更多相关文章

  1. cdoj 71 I am Lord Voldemort 水题

    I am Lord Voldemort Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/ ...

  2. 【题解】CF#855 G-Harry Vs Voldemort

    个人感觉挺有意思的,然而被颜神D无聊惹(- ̄▽ ̄)- 这题我们可以首先试图去统计以每一个点作为 w 点所能对答案造成的贡献是多少.不难发现,当且仅当 u 和 v 都在 w 所在边双的一侧的时候不能构成 ...

  3. Solution -「CF 855G」Harry Vs Voldemort

    \(\mathcal{Description}\)   Link.   给定一棵 \(n\) 个点的树和 \(q\) 次加边操作.求出每次操作后,满足 \(u,v,w\) 互不相等,路径 \((u,w ...

  4. 非关系型数据库(NoSql)

    最近了解了一点非关系型数据库,刚刚接触,觉得这是一个很好的方向,对于大数据 方面的处理,非关系型数据库能起到至关重要的地位.这里我主要是整理了一些前辈的经验,仅供参考. 关系型数据库的特点 1.关系型 ...

  5. PayPal高级工程总监:读完这100篇论文 就能成大数据高手(附论文下载)

    100 open source Big Data architecture papers for data professionals. 读完这100篇论文 就能成大数据高手 作者 白宁超 2016年 ...

  6. Index

    我主要在研究.NET/C# 实现 PC IMERP 和 Android IMERP ,目的在解决企业通信中遇到的各类自动化问题   分布式缓存框架: Microsoft Velocity:微软自家分布 ...

  7. Day12-mysql&&redis

    1. 数据库介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数 ...

  8. 1、NoSQL概述

    最近抽时间把Redis学了一下,所以就在网上找了一些资料.然后找到尚硅谷-周阳老师的视频教程,觉得里面的讲的挺好.所以就把他视频当中的资料教程整理出来. 单机MySQL的美好时代 在90年代,一个网站 ...

  9. NOSQL数据模型和CAP原理

    NOSQL数据模型和CAP原理 http://blog.sina.com.cn/s/blog_7800d9210100t33v.html 我本来一直觉得NoSQL其实很容易理解的,我本身也已经对NoS ...

随机推荐

  1. Authorization源码解析

    1.首先调用 Subject.isPermitted*/hasRole* 接口,其会委托给SecurityManager.SecurityManager 接着会委托给 Authorizer: Auth ...

  2. fastjson反序列化使用不当导致内存泄露

    分析一个线上内存告警的问题时,发现了造成内存告警的原因是使用fastjson不当导致的. 分析dump发现com.alibaba.fastjson.util.IdentityHashMap$Entry ...

  3. Microsoft.AspNet.Identity 自定义使用现有的表—登录实现,aspnet.identity

    Microsoft.AspNet.Identity是微软新引入的一种membership框架,也是微软Owin标准的一个实现.Microsoft.AspNet.Identity.EntityFrame ...

  4. Spring AOP创建BeforeAdvice和AfterAdvice实例

    BeforeAdvice 1.会在目标对象的方法执行之前被调用. 2.通过实现MethodBeforeAdvice接口来实现. 3.该接口中定义了一个方法即before方法,before方法会在目标对 ...

  5. MVC-10HTML助手

    HTML帮助器用于修改HTML输出. HTML帮助器 通过MVC,HTML帮助器类似于传统的ASP.NET Web Form控件. 类似ASP.NET中的web form控件,HTML帮助器用于修改H ...

  6. 删除链表的倒数第 n 个节点

    难度: 中等 leetcode地址: https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/ 分析: 1 ...

  7. Mongodb 学习笔记(一)

    MongoDB 是一款开源.跨平台.分布式,具有大数据处理能力的文档存储数据库.在 2007 年由 MongoDB 软件公司开发完成,并实现全部代码源发展.目 前,该文档数据库被国内外众多知名网因所采 ...

  8. 解决此报错:Cannot create Woodstox XMLInputFactory: java.lang.NoClassDefFoundError: com/ctc/wstx/stax/WstxInput

    最近在研究webservice服务的技术,可是写完webservice例子后,项目正常启动,但是在输入url地址后报如下的错误: Cannot create Woodstox XMLInputFact ...

  9. ceph luminous版部署bluestore

    简介 与filestore最大的不同是,bluestore可以直接读写磁盘,即对象数据是直接存放在裸设备上的,这样解决了一直被抱怨的数据双份写的问题 Bluestore直接使用一个原始分区来存放cep ...

  10. 如何方便引用自己的python包

    有时候想要把一些功能封装成函数然后包装到模块里面最后形成一个包,然后在notebook里面去引用它去处理自己的数据和分析一些有用的部分,比如自己在 之前用到的一个datascience模板就是这样组织 ...