[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))\)。

源代码:

#include<cstdio>
#include<cctype>
#include<vector>
#include<numeric>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=1e5+1;
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
int64 ans,val[N],tmp[N];
int n,par[N],dep[N],size[N],tsize[N];
struct DisjointSet {
int anc[N];
void reset(const int &n) {
std::iota(&anc[1],&anc[n]+1,1);
}
int find(const int &x) {
return x==anc[x]?x:anc[x]=find(anc[x]);
}
void merge(const int &x,const int &y) {
anc[find(x)]=find(y);
}
bool same(const int &x,const int &y) {
return find(x)==find(y);
}
};
DisjointSet djs;
void dfs(const int &x,const int &par) {
::par[x]=par;
dep[x]=dep[par]+1;
size[x]=tsize[x]=1;
for(int y:e[x]) {
if(y==par) continue;
dfs(y,x);
tsize[x]+=tsize[y];
}
}
int64 calc(const int &x) {
int64 ans=0;
ans+=1ll*size[x]*(size[x]-1)*(size[x]-2);//XXX
ans+=2ll*size[x]*(size[x]-1)*(n-size[x]);//XX-Y & Y-XX
ans+=1ll*(n-size[x])*(n-size[x])*size[x];
for(int y:e[x]) {//Y-X-Z & Z-X-Y
if(djs.same(x,y)) continue;
const int z=djs.find(y);
const int sz=y==par[x]?n-tsize[x]:tsize[z];
ans-=1ll*sz*sz*size[x];
tmp[x]+=1ll*sz*sz;
}
return val[x]=ans;
}
int64 calc2(const int &x) {
int64 ans=0;
ans+=1ll*size[x]*(size[x]-1)*(size[x]-2);//XXX
ans+=2ll*size[x]*(size[x]-1)*(n-size[x]);//XX-Y & Y-XX
ans+=1ll*(n-size[x])*(n-size[x])*size[x];//Y-X-Z & Z-X-Y
ans-=tmp[x]*size[x];
return val[x]=ans;
}
void merge(int u,int v) {
u=djs.find(u);
v=djs.find(v);
while(u!=v) {
if(dep[u]<dep[v]) std::swap(u,v);
const int w=djs.find(par[u]);
tmp[w]-=1ll*tsize[u]*tsize[u];
tmp[w]+=tmp[u]-1ll*(n-tsize[u])*(n-tsize[u]);
ans-=val[u];
size[w]+=size[u];
djs.merge(u,w);
u=w;
}
ans-=val[u];
ans+=calc2(u);
}
int main() {
n=getint();
for(register int i=1;i<n;i++) {
add_edge(getint(),getint());
}
djs.reset(n);
dfs(1,0);
for(register int x=1;x<=n;x++) {
ans+=calc(x);
}
printf("%lld\n",ans);
const int q=getint();
for(register int i=0;i<q;i++) {
merge(getint(),getint());
printf("%lld\n",ans);
}
return 0;
}

[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. axios ios 微信浏览器session问题

    在ios系统下,微信浏览器使用axios 可能存在seesion不存在的问题,其原因是因为存在跨域 解决方案如下 1.修改域名为同一域名 2.后台允许跨域

  2. Java的集合整理

    1.List和Set都是接口,他们都继承于接口Collection,List是一个有序的可重复的集合,而Set的无序的不可重复的集合.Collection是集合的顶层接口,Collections是一个 ...

  3. Navicat 连接mysql 报错: Authentication plugin caching_ sha2_password cannot be loaded

    出现这个错误的时候, 网上的资料都是修改mysql的登录信息的, ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password ...

  4. HTTP API 认证授权术

    原文:https://coolshell.cn/articles/19395.html 我们知道,HTTP是无状态的,所以,当我们需要获得用户是否在登录的状态时,我们需要检查用户的登录状态,一般来说, ...

  5. iOS - xcode经常报的经典error解决办法大全

    1.错误信息: 2015-10-28 10:39:55.933 XFW[2696:55982] *** Assertion failure in -[UITableView _configureCel ...

  6. 【转载】C#使用Math.Sqrt方法进行开平方操作

    在C#的数学数值运算中,有时候需要进行对数值进行开平方操作,C#的数值计算类Math类中内置了开平方操作的方法Sqrt,直接调用此方法可计算出相应的平方值,Math.Sqrt方法签名为:double ...

  7. 解决internal/modules/cjs/loader.js:638 throw err; ^ Error: Cannot find module 'resolve'

    internal/modules/cjs/loader.js:638 throw err; ^ Error: Cannot find module 'resolve' 根据提示可以知道有依赖没有安装完 ...

  8. Java 之 Servlet 基础入门

    Servlet 一.什么是 Servlet 1.概念 Servlet:server applet,是指运行在服务器端的小程序 2.Servlet   servlet 就是一个接口,定义了 Java 类 ...

  9. [AIR] NativeExtension在IOS下的开发实例 --- Flex库项目的创建(二)

    来源:http://bbs.9ria.com/thread-102038-1-1.html 上一章,我已经介绍了如果创建IOS库文件,并定义了两个方法ShowIconBadageNumber和Init ...

  10. Android笔记(四十) Android中的数据存储——SQLite(二) insert

    准备工作: 我们模拟一个注册的页面,先看UI 我们需要创建一个数据库:user,数据库包含表user,user表包含字段id.username.password.mobilephone MainAct ...