【题解】CF#855 G-Harry Vs Voldemort
个人感觉挺有意思的,然而被颜神D无聊惹(~ ̄▽ ̄)~
这题我们可以首先试图去统计以每一个点作为 w 点所能对答案造成的贡献是多少。不难发现,当且仅当 u 和 v 都在 w 所在边双的一侧的时候不能构成一个合法的三元组,因为它们要到达 w 均需经过一条共同的割边。那么因为原图是一棵树,所以我们连接两个点的时候就是在把这两个点所在的边双一直到根所在的边双都合并为一个。
考虑如何在合并答案的时候计算出答案的变化。若我们合并的是 S,T 这两个集合,我们可以先减去由 S 和 T 中的点作为 w 点时对答案造成的贡献。1.u 和 v 均为 w 所在边双中的点,这个直接用边双大小统计就可以了;2.一个在边双外部,一个在边双内部。这个也可以直接用边双大小进行统计。
比较难想到的是如何统计两个点都在边双外部的情况(在边双的两侧)。这个直接统计并不是很方便,但是不难发现如果统计在点双外部且在两侧的情况是很多的,而在点双外部且在同一侧的情况则单一很多。全部的选择就是点双外部的点钟随便选两个,我们可以把在同一侧的情况减去得到合法的解。维护数组 w[u] 表示 u 联通块中的一个点所能匹配到的同一侧的两个点有多少种方案。非法的情况即为 w[u] * s[u] (u 联通块的大小)。合并的时候 w 数组怎么合并呢?令 u 为 v 的父亲,则 w[u] + w[v] 这样统计的话会把 v 所在的子树内的点对 & v 点外部(父亲子树)的点对统计两次。减去就好啦。
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000000
#define int long long
int n, ans, s[maxn], w[maxn], dep[maxn];
int size[maxn], fa[maxn], f[maxn]; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} struct edge
{
int cnp, to[maxn], last[maxn], head[maxn];
edge() { cnp = ; }
void add(int u, int v)
{
to[cnp] = v, last[cnp] = head[u], head[u] = cnp ++;
to[cnp] = u, last[cnp] = head[v], head[v] = cnp ++;
}
}E1; void dfs(int u)
{
size[u] = ; dep[u] = dep[fa[u]] + ;
for(int i = E1.head[u]; i; i = E1.last[i])
{
int v = E1.to[i];
if(v == fa[u]) continue;
fa[v] = u; dfs(v);
size[u] += size[v]; w[u] += size[v] * size[v];
}
w[u] += (n - size[u]) * (n - size[u]);
ans -= w[u];
} int Cal(int u) { return max(s[u] * (s[u] - ) * (s[u] - ), 0LL); }
int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
void merge(int u, int v)
{
ans -= (n - s[u]) * (n - s[u]) * s[u] - w[u] * s[u];
ans -= (n - s[v]) * (n - s[v]) * s[v] - w[v] * s[v];
ans -= (n - s[u]) * s[u] * (s[u] - ) * ;
ans -= (n - s[v]) * s[v] * (s[v] - ) * ;
ans -= Cal(u) + Cal(v); f[v] = u, s[u] += s[v]; w[u] += w[v] - size[v] * size[v] - (n - size[v]) * (n - size[v]);
ans += (n - s[u]) * (n - s[u]) * s[u] - w[u] * s[u] + Cal(u);
ans += (n - s[u]) * s[u] * (s[u] - ) * ;
} signed main()
{
n = read();
for(int i = ; i < n; i ++)
{
int u = read(), v = read();
E1.add(u, v);
}
ans = n * (n - ) * (n - ); dfs();
for(int i = ; i <= n; i ++) f[i] = i, s[i] = ;
int q = read();
printf("%lld\n", ans);
for(int i = ; i <= q; i ++)
{
int u = read(), v = read();
u = find(u), v = find(v);
while(u != v)
{
if(dep[u] < dep[v]) swap(u, v);
int fu = find(fa[u]);
merge(fu, u); u = fu;
}
printf("%lld\n", ans);
}
return ;
}
【题解】CF#855 G-Harry Vs Voldemort的更多相关文章
- [题解向] CF#Global Round 1の题解(A $\to$ G)
这里是总链接\(Link\). \(A\) 题意:求\(\sum_{i=1}^{k} a_i\times b^{k-i}\)的奇偶性, \(k = \Theta(n \log n)\) --其实很容易 ...
- 竞赛题解 - CF Round #524 Div.2
CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...
- 题解 CF 1372 B
题目 传送门 题意 给出 \(n\),输出 \(a\) ,\(b\) (\(0 < a \leq b < n\)),使\(a+b=n\)且 \(\operatorname{lcm}(a,b ...
- 题解——CF Manthan, Codefest 18 (rated, Div. 1 + Div. 2) T5(思维)
还是dfs? 好像自己写的有锅 过不去 看了题解修改了才过qwq #include <cstdio> #include <algorithm> #include <cst ...
- CF 1051 G. Distinctification
G. Distinctification 链接 分析: 线段树合并 + 并查集. 最后操作完后a连续递增的一段,b一定是递减的.最后的答案是$\sum (a_{new}-a_{odd}) \times ...
- CF 724 G. Xor-matic Number of the Graph
G. Xor-matic Number of the Graph 链接 题意: 给定一个无向图,一个interesting的三元环(u,v,s)满足,从u到v的路径上的异或和等于s,三元环的权值为s, ...
- CF 1093 G. Multidimensional Queries
G. Multidimensional Queries 链接 分析: 考虑如何去掉绝对值符号. $\sum \limits_{i = 1}^{k} |a_{x, i} - a_{y, i}|$,由于k ...
- 【codeforces】【比赛题解】#855 Codefest 17
神秘比赛,以<哈利波特>为主题……有点难. C题我熬夜切终于是写出来了,可惜比赛结束了,气啊. 比赛链接:点我. [A]汤姆·里德尔的日记 题意: 哈利波特正在摧毁神秘人的分灵体(魂器). ...
- 竞赛题解 - [CF 1080D]Olya and magical square
Olya and magical square - 竞赛题解 借鉴了一下神犇tly的博客QwQ(还是打一下广告) 终于弄懂了 Codeforces 传送门 『题目』(直接上翻译了) 给一个边长为 \( ...
随机推荐
- cookie的介绍和自动化中cookie的操作
1 cookie是什么? cookie: 1. Cookie是一小段的文本信息:格式:python中的字典(键值对组成) 2. Cookie产生:客户端请求服务器,如果服务器需要记录该用户状态,就向客 ...
- 使用jenkins构建一个maven项目
1.登陆到jenkins首页,创建项目-->选择maven-->输入项目名称-->选择项目类型 2.进入项目配置:{先写一下项目描述和设置下保留的历史构建,然后向下拉} 找到源吗管理 ...
- linux 学习总结---- mysql 总结
用户的创建 ---->修改 ---->删除用户 create alter drop (数据定义语言 DDL) 授权: insert update delete grant *.* revo ...
- 总结获取原生JS(javascript)基本操作
var a = document.getElementByIdx_x_x("dom"); jsCopy(a);//调用清理空格的函数 var b = a.childNodes;// ...
- Android开发-API指南-<activity>
<activity> 英文原文:http://developer.android.com/guide/topics/manifest/activity-element.html 采集(更新 ...
- 【Linux 运维】Centos7初始化网络配置
设置网络 (1)动态获取一个IP地址 #dhclient 系统自动自动获取一个IP地址#ip addr 查看获取的ip地址(2)查看网关,子网掩码 虚拟机编辑>虚拟 ...
- NMAP-高级用法
1.报文分段 2.偏移 –mtu后面的数字是8的倍数 3.源端口欺骗 4.指定报文长度 5.ttl 6.mac地址伪造 0代表随机伪造 7.正常输出 8.输出为xml 9.输出为grep 10.输出所 ...
- OJ错误命令解释
①Presentation Error (PE) : 虽然您的程序貌似输出了正确的结果,但是这个结果的格式有点问题. 请检查程序的输出是否多了或者少了空格(' ').制表符('\t')或者换行符('\ ...
- c# windows service 程序
service服务程序:可以长时间运行可执行应用程序.没有用户界面.可以自动启动和手动启动.适用于在服务器上或需要干扰其他工作的用户可以在同一台计算机上长时间的运行此功能. C#创建service服务 ...
- Java语法基础课后作业
1.动手动脑 运行它EnumTest.java,分析运行结果 s和t分别引用的是SMALL和LARGE,枚举类型不是原始数据类型,s和u的赋值方式不同,但结果一样,列出它的所有值:SMALL,MEDI ...