[CF855G]Harry Vs Voldemort
[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)\):
- \(u,v,w\)均在同一个边双中;
- \(u,v\)中有一个在与\(w\)相同的边双中;
- \(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的更多相关文章
- cdoj 71 I am Lord Voldemort 水题
I am Lord Voldemort Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/ ...
- 【题解】CF#855 G-Harry Vs Voldemort
个人感觉挺有意思的,然而被颜神D无聊惹(- ̄▽ ̄)- 这题我们可以首先试图去统计以每一个点作为 w 点所能对答案造成的贡献是多少.不难发现,当且仅当 u 和 v 都在 w 所在边双的一侧的时候不能构成 ...
- Solution -「CF 855G」Harry Vs Voldemort
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个点的树和 \(q\) 次加边操作.求出每次操作后,满足 \(u,v,w\) 互不相等,路径 \((u,w ...
- 非关系型数据库(NoSql)
最近了解了一点非关系型数据库,刚刚接触,觉得这是一个很好的方向,对于大数据 方面的处理,非关系型数据库能起到至关重要的地位.这里我主要是整理了一些前辈的经验,仅供参考. 关系型数据库的特点 1.关系型 ...
- PayPal高级工程总监:读完这100篇论文 就能成大数据高手(附论文下载)
100 open source Big Data architecture papers for data professionals. 读完这100篇论文 就能成大数据高手 作者 白宁超 2016年 ...
- Index
我主要在研究.NET/C# 实现 PC IMERP 和 Android IMERP ,目的在解决企业通信中遇到的各类自动化问题 分布式缓存框架: Microsoft Velocity:微软自家分布 ...
- Day12-mysql&&redis
1. 数据库介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数 ...
- 1、NoSQL概述
最近抽时间把Redis学了一下,所以就在网上找了一些资料.然后找到尚硅谷-周阳老师的视频教程,觉得里面的讲的挺好.所以就把他视频当中的资料教程整理出来. 单机MySQL的美好时代 在90年代,一个网站 ...
- NOSQL数据模型和CAP原理
NOSQL数据模型和CAP原理 http://blog.sina.com.cn/s/blog_7800d9210100t33v.html 我本来一直觉得NoSQL其实很容易理解的,我本身也已经对NoS ...
随机推荐
- 全栈项目|小书架|服务器开发-Koa2 参数校验处理
为什么需要做参数校验 在开发中,无论是App开发还是服务器接口开发, 我们无法去预测用户传入的数据,因此参数(数据)校验是开发中不可或缺的一环. 例如像App的注册登录表单提交页面,就要做好多层的判断 ...
- JNA的应用
一.了解JNA之前,我们先了解一下JNA的前身JNI(Java Native Interface):通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植. [1] 从Java1.1 ...
- C# 生成随机的6位字母,包含大小写
今天自己做项目需要生成随机的6位字母,于是自己写了一个,下面代码是可以生成任意位数字母的. string _zimu = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg ...
- PowerShell命令批量添加、导出AD用户
导入单个AD用户命令 New-ADUser -Name "周八" -Surname "周" -GivenName "八"-SamAccoun ...
- 前端开发 vue,angular,react框架对比2
在过去一年里,前端开发发展迅速,前端工程师的薪资亦是水涨船高.2019 更是热度不减,而作为近年来尤为热门的前端框架,Vue.js 自是积累了大量关注.那么,Vue.js 是适合你的框架吗? ...
- 机器码-字节码-CLR-JIT-托管代码-非托管代码-unsafe-GC-fixed
0. 机器码 直接由机器码对应平台的CPU执行的指令集, 因此无法在其他指令集的CPU上运行. 无法跨平台. 由本地代码编译得到. (托管代码通过JIT生成) 1. 字节码 即 bytecode 是一 ...
- Qt 利用飞机图片画五边形
最近练习Qt,需要一个飞机在屏幕上画五边形.虽然达到的效果不是非常的理想,但是勉强还是达到了效果,欢迎大家指正.用到的飞机图片如下. 第一步:初始化,在构造函数里面,把图片向左旋转18° );ui.l ...
- SAP Marketing Cloud功能简述(五) : 销售计划管理
Grace前四篇介绍SAP Marketing Cloud的文章: SAP Marketing Cloud功能简述(一) : Contacts和Profiles SAP Marketing Cloud ...
- WPF如何设置启动窗口
在做系统时,我们想在启动时显示自己想显示的界面,和Winform不同的是它有两种方法 1.在App.xaml中 <Application x:Class="WpfApp1.App&qu ...
- Linux ping:unknown host问题排查
一.检查网卡配置:输入ifconfig可以查看当前网卡配置的IP地址并且查看配置文件中网络的设置: [root@bqh- ~]# ifconfig eth0 Link encap:Ethernet H ...