CF855G Harry Vs Voldemort

根据 hater\tt\color{black}{h}\color{red} aterhater 的话,这个东西放到现在有 280028002800。

显然恶评。

就是对于一个 333 元组,我们发现本质就是树上两条路径合并的问题,那么我们像淀粉质一样将每个点作为 Lca\tt LcaLca 计算答案即可。

那么一开始的答案就是 ansu=(n−1)×(n−1)−∑v∈sonusizv×sizv−(n−sizu)×(n−sizu)ans_u = (n - 1) \times (n - 1) - \sum_{v \in son_u} siz_v \times siz_v - (n - siz_u) \times (n - siz_u)ansu​=(n−1)×(n−1)−∑v∈sonu​​sizv​×sizv​−(n−sizu​)×(n−sizu​)。

本质上就是考虑不取当前的点,任意的点对,为了方便我们就是考虑到 (i,i)(i, i)(i,i) 这样的点对,反正也会减去的。

之后考虑加入一条边就是增加一个环,那么我们对于环中的每一个点的答案本质是相同的,我们对于一个环可以一起计算,不妨设其深度最浅的节点为 uuu,整个环的儿子集合为 sonsonson,整个环的元素个数是 sss。

  • 都在环上 s×(s−1)×(s−2)s \times (s - 1) \times (s - 2)s×(s−1)×(s−2)。
  • 一个在环上 2×(s−1)×(n−s)2 \times (s - 1) \times (n - s)2×(s−1)×(n−s) 钦定一个中间节点,然后两倍是因为两个点可以交换。
  • 都不在环上 (n−s)×(n−s)−∑v∈sonsizv×sizv−sizu×sizu(n - s) \times (n - s) - \sum_{v \in son} siz_v \times siz_v - siz_u \times siz_u(n−s)×(n−s)−∑v∈son​sizv​×sizv​−sizu​×sizu​。

最后只要乘上元素的个数就是整个环的答案。

新增加一条边的时候,那么肯定是形成一个大的双联通分量,那么中间的每个点都需要被合并。我们直接对于每一个双联通分量暴力跳父亲合并即可。

复杂度是 O(nlog⁡n)O(n \log n)O(nlogn),如果并查集使用路径压缩和按秩合并的话是 O(nα(n))O(n \alpha(n))O(nα(n))。

#include <bits/stdc++.h>
using namespace std;//#define Fread
//#define Getmod#ifdef Fread
char buf[1 << 21], *iS, *iT;
#define gc() (iS == iT ? (iT = (iS = buf) + fread (buf, 1, 1 << 21, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
#define getchar gc
#endif // Freadtemplate <typename T>
void r1(T &x) {x = 0;char c(getchar());int f(1);for(; c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;for(; '0' <= c && c <= '9';c = getchar()) x = (x * 10) + (c ^ 48);x *= f;
}#ifdef Getmod
const int mod  = 1e9 + 7;
template <int mod>
struct typemod {int z;typemod(int a = 0) : z(a) {}inline int inc(int a,int b) const {return a += b - mod, a + ((a >> 31) & mod);}inline int dec(int a,int b) const {return a -= b, a + ((a >> 31) & mod);}inline int mul(int a,int b) const {return 1ll * a * b % mod;}typemod<mod> operator + (const typemod<mod> &x) const {return typemod(inc(z, x.z));}typemod<mod> operator - (const typemod<mod> &x) const {return typemod(dec(z, x.z));}typemod<mod> operator * (const typemod<mod> &x) const {return typemod(mul(z, x.z));}typemod<mod>& operator += (const typemod<mod> &x) {*this = *this + x; return *this;}typemod<mod>& operator -= (const typemod<mod> &x) {*this = *this - x; return *this;}typemod<mod>& operator *= (const typemod<mod> &x) {*this = *this * x; return *this;}int operator == (const typemod<mod> &x) const {return x.z == z;}int operator != (const typemod<mod> &x) const {return x.z != z;}
};
typedef typemod<mod> Tm;
#endiftemplate <typename T,typename... Args> inline void r1(T& t, Args&... args) {r1(t);  r1(args...);
}//#define int long long
const int maxn = 2e5 + 5;
const int maxm = maxn << 1;signed main() {//    freopen("S.in", "r", stdin);
//    freopen("S.out", "w", stdout);int i, j, n;struct DSU : vector<int>{DSU(int n = 0) { this->resize(n + 1); }int getfa(int x) {return x == this->at(x) ? x : this->at(x) = getfa(this->at(x));}};r1(n);vector<vector<int>> vc(n + 1);auto add = [&] (int u,int v) -> void{vc[u].emplace_back(v);};for(i = 1; i < n; ++ i) {int u, v; r1(u, v);add(u, v), add(v, u);}vector<int> dep(n + 1, 0), siz(n + 1, 0), rp(n + 1, 0), fa(n + 1, 0);vector<long long> val(n + 1, 0ll);function<void(const int&, int)> dfs;dfs = [&](const int& p,int pre) -> void{rp[p] = siz[p] = 1;fa[p] = pre;for(auto v : vc[p]) if(v != pre) {dep[v] = dep[p] + 1;dfs(v, p);siz[p] += siz[v];val[p] += 1ll * siz[v] * siz[v];}};dfs(1, 0);DSU T(n);for(i = 1; i <= n; ++ i) T[i] = i;long long ans(0);auto Bef = [=, &ans]() -> void{for(int i = 1; i <= n; ++ i) ans += 1ll * (n - 1) * (n - 1) - val[i] - 1ll * (n - siz[i]) * (n - siz[i]);};Bef();auto Calc = [&] (const int &u, const int &opt) -> void{assert(u == T.getfa(u));long long s = rp[u];ans += opt * s * (s - 1) * (s - 2);ans += 2 * opt * s * (s - 1) * (n - s);
//        printf("s = %d\n", s);ans += opt * s * ( 1ll * (n - s) * (n - s) - val[u] - 1ll * (n - siz[u]) * (n - siz[u]) );};auto Merge = [&] (const int &u, const int &v) -> void{ // dep[u] < dep[v]
//        puts("SSSS");
//        printf("u = %d, v = %d\n", u, v);
//        printf("u = %d, v = %d\n", dep[u], dep[v]);
//        assert(T.getfa(u) == u && T.getfa(v) == v && dep[u] < dep[v]);assert(T.getfa(u) == u && T.getfa(v) == v);Calc(u, -1), Calc(v, -1);val[u] -= 1ll * siz[v] * siz[v]; // 合并肯定是直接连接的val[u] += val[v];rp[u] += rp[v];
//        printf("ans = %lld\n", ans);Calc(u, 1);auto merge = [&] (int x,int y) -> void{x = T.getfa(x), y = T.getfa(y);
//            printf("x = %d, y = %d\n", x, y);if(x != y) T[y] = x;};merge(u, v);};printf("%lld\n", ans);int m; r1(m);while(m --) {int u, v; r1(u, v);while(T.getfa(u) != T.getfa(v)) {if(dep[T.getfa(u)] < dep[T.getfa(v)]) swap(u, v);
//            printf("u = %d, v = %d\n", u, T.getfa(fa[u]));u = T.getfa(u);Merge(T.getfa(fa[u]), u);}printf("%lld\n", ans);}return 0;
}

先说一下抱歉,这里的码风比较奇怪,因为这题比较简单那么久顺便练习一下 c++14\tt c++14c++14 的语法和知识点。

但是好处是每一个函数调用时比较明确的。

CF855G Harry Vs Voldemort 题解相关推荐

  1. [JS][dfs]题解 | #迷宫问题#

    题解 | #迷宫问题# 题目链接 迷宫问题 题目描述 定义一个二维数组 N*M ,如 5 × 5 数组下所示: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 1, 1 ...

  2. [JS][dp]题解 | #打家劫舍(一)#

    题解 | #打家劫舍(一)# 题目链接 打家劫舍(一) 题目描述 描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家, ...

  3. [JS]题解 | #魔法数字#

    题解 | #魔法数字# 题目链接 魔法数字 题目描述 牛妹给牛牛写了一个数字n,然后又给自己写了一个数字m,她希望牛牛能执行最少的操作将他的数字转化成自己的. 操作共有三种,如下: 在当前数字的基础上 ...

  4. [JS]题解 | #岛屿数量#

    题解 | #岛屿数量# 题目链接 岛屿数量 题目描述 时间限制:1秒 空间限制:256M 描述 给一个01矩阵,1代表是陆地,0代表海洋, 如果两个1相邻,那么这两个1属于同一个岛.我们只考虑上下左右 ...

  5. [JS] 题解:提取不重复的整数

    题解:提取不重复的整数 https://www.nowcoder.com/practice/253986e66d114d378ae8de2e6c4577c1 时间限制:1秒 空间限制:32M 描述 输 ...

  6. 洛谷-题解 P2672 【推销员】

    独门思路!链表加优先队列! 这题一望,贪心是跑不掉了,但是我贪心并不好,所以想到了一个复杂一些但思路更保稳的做法 思路: 1 因为是离线操作,所以我们可以倒着求,先求x=n的情况,因为那样直接就知道了 ...

  7. [洛谷1383]高级打字机 题解

    题解 这道题一看就珂以用主席树啊 这是一道神奇的题目,那么我们先敲一个主席树,然后维护一个数组len,表示下一次应该在len + 1插入, 之后对于T操作,在上一个版本的len + 1上直接执行插入 ...

  8. luogu P1549 棋盘问题(2) 题解

    luogu P1549 棋盘问题(2) 题解 题目描述 在\(N * N\)的棋盘上\((1≤N≤10)\),填入\(1,2,-,N^2\)共\(N^2\)个数,使得任意两个相邻的数之和为素数. 例如 ...

  9. 【题解搬运】PAT_L1-009 N个数求和

    从我原来的博客上搬运.原先blog作废. (伪)水题+1,旨在继续摸清这个blog(囧 题目 就是求N个数字的和.麻烦的是,这些数字是以有理数"分子/分母"的形式给出的,你输出的和 ...

  10. 第五届合肥工业大学宣城校区程序设计大赛题解

    问题 A: 小问题 时间限制: 1 Sec  内存限制: 128 MB  Special Judge 题目描述 林喵喵特别喜欢解决女孩子们提出的问题. 于是, 有一天殷老师问了林喵喵一个小问题. 给出 ...

最新文章

  1. 英伟达CEO黄仁勋获芯片行业最高荣誉:他颠覆了计算!
  2. Call From hadoop102/192.168.121.102 to hadoop102:9000 failed on connection exception
  3. 为什么姜黄素+胡椒碱会让姜黄素吸收率增加2000%以上
  4. 邻接表存储图利用BFS遍历
  5. express不是内部或外部命令,也不是可运行的程序或批处理文件
  6. java eden分配参数,JVM垃圾收集器与内存分配策略,
  7. java拼装树_java 数据拼装成树结构
  8. 第 7 章 Neutron - 075 - 为 Neutron 准备物理基础设施(I)
  9. CSS3淘宝支付成功打勾动画代码
  10. 【黑苹果教程】Airport-miniPCIe 无线网卡驱动
  11. 如何解读springboot 中约定大于配置、JPA是什么、咋用
  12. 服务器分类方式和类型
  13. 思科路由器及交换机基本配置
  14. 策划好一场活动的要点和方法有哪些?
  15. 反转二叉树--递归和非递归
  16. iOS 仿钉钉文字水印
  17. 数据类型、字符编码、文件处理
  18. Python — 文字输出乱码
  19. Scratch3.0——助力新进程序员理解程序(案例八、等差数列计算1)
  20. Terraform 和 Oracle Cloud Infrastructure

热门文章

  1. 原始股的股份怎么进行分红
  2. Workflow(12) DNSResolver
  3. UESTC878————温泉旅店(动态规划)
  4. 【Unity学习】Unity GetCurrentAnimatorStateInfo方法判断动画播放
  5. 安装程序无法打开注册表项 UNKNOWN\Components\…的简单解决办法
  6. STM32F7+STM32CubeMX5.21+SD+FATFS
  7. 武汉大学计算机学院2010情景剧,武汉大学金秋情景剧大赛精彩落幕(组图)
  8. RocketMQ消息存储学习
  9. html中siblings方法,jQuery siblings()方法的用法
  10. cocos 躲避球游戏(3) --群组碰撞