vjudge

首先显然要建立圆方树

对于每一种点建立虚树,考虑这一种点贡献,对于虚树上已经有的点就直接算

否则对虚树上的一条边 \((u, v)\),\(u\) 为父亲,假设上面连通块大小为 \(x\),下面为 \(y\)

切断 \((u, v)\) 之间的点(不包括 \(u\))都会有 \(x\times y\) 的贡献,差分一下贡献即可

# include <bits/stdc++.h>
using namespace std;
typedef long long ll; namespace IO {
const int maxn(1 << 21 | 1); char ibuf[maxn], obuf[maxn], *iS, *iT, *oS = obuf, *oT = obuf + maxn - 1, c, st[66];
int tp, f; inline char Getc() {
return iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, maxn, stdin), (iS == iT ? EOF : *iS++)) : *iS++;
} template <class Int> inline void In(Int &x) {
for (f = 1, c = Getc(); c < '0' || c > '9'; c = Getc()) f = c == '-' ? -1 : 1;
for (x = 0; c >= '0' && c <= '9'; c = Getc()) x = (x << 1) + (x << 3) + (c ^ 48);
x *= f;
} inline void Flush() {
fwrite(obuf, 1, oS - obuf, stdout);
oS = obuf;
} inline void Putc(char c) {
*oS++ = c;
if (oS == oT) Flush();
} template <class Int> void Out(Int x) {
if (!x) Putc('0');
if (x < 0) Putc('-'), x = -x;
while (x) st[++tp] = x % 10 + '0', x /= 10;
while (tp) Putc(st[tp--]);
}
} using IO :: In;
using IO :: Out;
using IO :: Putc;
using IO :: Flush; const int maxn(4e5 + 5); int n, m, g[maxn], size[maxn], son[maxn], fa[maxn], top[maxn], tot, d[maxn], f[maxn], ng;
int dfn[maxn], low[maxn], st[maxn], tp, idx, deep[maxn], id[maxn], cnt, sz, nsz, dsu[maxn];
vector <int> e1[maxn], e2[maxn], e3[maxn], team[maxn * 3];
ll ans[maxn], cv[maxn], add; inline void Add1(int u, int v) {
e1[u].push_back(v), e1[v].push_back(u);
} inline void Add2(int u, int v) {
e2[u].push_back(v), e2[v].push_back(u);
} inline void Add3(int u, int v) {
e3[u].push_back(v), ++d[v];
} void Tarjan(int u) {
int cur;
dfn[u] = low[u] = ++idx, st[++tp] = u;
for (auto v : e1[u])
if (!dfn[v]) {
Tarjan(v), low[u] = min(low[u], low[v]);
if (low[v] >= dfn[u]) {
++tot;
do {
cur = st[tp--], Add2(cur, tot);
} while (cur ^ v);
Add2(u, tot);
}
}
else low[u] = min(low[u], dfn[v]);
} void Dfs1(int u, int ff) {
size[u] = 1;
for (auto v : e2[u])
if (v ^ ff) {
deep[v] = deep[u] + 1, fa[v] = u;
Dfs1(v, u), size[u] += size[v];
son[u] = size[v] > size[son[u]] ? v : son[u];
}
} void Dfs2(int u, int tp) {
top[u] = tp, dfn[u] = ++idx;
if (son[u]) Dfs2(son[u], tp);
for (auto v : e2[u]) if (!top[v]) Dfs2(v, v);
} inline int Find(int x) {
return (dsu[x] ^ x) ? dsu[x] = Find(dsu[x]) : x;
} inline int Cmp(int x, int y) {
return dfn[x] < dfn[y];
} inline int LCA(int u, int v) {
while (top[u] ^ top[v]) deep[top[u]] > deep[top[v]] ? u = fa[top[u]] : v = fa[top[v]];
return deep[u] < deep[v] ? u : v;
} void Getsz(int u) {
if (g[u] == ng) ++nsz;
for (auto v : e3[u]) Getsz(v);
} void Calc(int u) {
if (g[u] == ng) f[u] = 1;
for (auto v : e3[u]) Calc(v), ans[u] += (ll)f[u] * f[v], f[u] += f[v];
for (auto v : e3[u]) cv[v] += (ll)(nsz - f[v]) * f[v], cv[u] -= (ll)(nsz - f[v]) * f[v];
} void Solve(int u, int ff) {
for (auto v : e2[u]) if (v ^ ff) Solve(v, u), cv[u] += cv[v];
ans[u] += cv[u];
} int main() {
int i, j, u, v, l;
In(n), In(m), tot = n;
for (i = 1; i <= n; ++i) In(g[i]), team[g[i]].push_back(i), dsu[i] = i;
for (i = 1; i <= m; ++i) {
In(u), In(v), Add1(u, v);
if (Find(u) ^ Find(v)) dsu[Find(u)] = Find(v);
}
for (i = 1; i <= n; ++i) if (!dfn[i]) Tarjan(i);
for (idx = 0, i = 1; i <= tot; ++i) if (!size[i]) Dfs1(i, 0), Dfs2(i, i);
for (i = 1; i <= 1000000; ++i)
if (l = team[i].size()) {
for (cnt = j = 0; j < l; ++j) id[++cnt] = team[i][j];
sort(id + 1, id + cnt + 1, Cmp);
for (j = 1; j < l; ++j) if (Find(id[j]) == Find(id[j + 1]))id[++cnt] = LCA(id[j], id[j + 1]);
sort(id + 1, id + cnt + 1, Cmp), cnt = unique(id + 1, id + cnt + 1) - id - 1;
for (j = 1; j <= cnt; ++j) e3[id[j]].clear(), f[id[j]] = d[id[j]] = 0;
sz = tp = 0, ng = i;
for (j = 1; j <= cnt; ++j) {
while (tp && dfn[st[tp]] + size[st[tp]] <= dfn[id[j]]) --tp;
if (tp) Add3(st[tp], id[j]);
st[++tp] = id[j];
}
for (j = 1; j <= cnt; ++j)
if (!d[id[j]]) nsz = 0, Getsz(id[j]), Calc(id[j]), add += (ll)sz * nsz, sz += nsz;
}
for (i = 1; i <= tot; ++i) if (!fa[i]) Solve(i, 0);
for (i = 1; i <= n; ++i) Out(ans[i] + add), Putc('\n');
return Flush(), 0;
}

CodeChef SADPAIRS:Chef and Sad Pairs的更多相关文章

  1. Chef 自动化运维:Chef 的安装

    安装准备 准备三台服务器,分别用作 Chef Server.Chef DK.Chef Client 的安装使用. 在三台服务器中,添加以下 hosts: vim /etc/hosts 192.168. ...

  2. Codechef Sad Pairs——圆方树+虚树+树上差分

    SADPAIRS 删点不连通,点双,圆方树 非割点:没有影响 割点:子树DP一下 有不同颜色,所以建立虚树 在圆方树上dfs时候 如果当前点是割点 1.统计当前颜色虚树上的不连通点对,树形DP即可 2 ...

  3. 云时代基础设置自动化管理利器: Chef

    云时代的到来势不可挡.尤其作为程序员,我们每天或多或少的直接或间接的使用者各种云服务.云平台有很多种,如云软件(SaaS, Software as a service).云平台(PaaS, Platf ...

  4. 【图像配准】基于灰度的模板匹配算法(一):MAD、SAD、SSD、MSD、NCC、SSDA、SATD算法

    简介: 本文主要介绍几种基于灰度的图像匹配算法:平均绝对差算法(MAD).绝对误差和算法(SAD).误差平方和算法(SSD).平均误差平方和算法(MSD).归一化积相关算法(NCC).序贯相似性检测算 ...

  5. CodeChef - SQRGOOD:Simplify the Square Root (求第N个含平方因子数)

    Tiny Wong the chef used to be a mathematics teacher in a senior high school. At that time, he always ...

  6. No.024:Swap Nodes in Pairs

    问题: Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1-> ...

  7. leetcode:Swap Nodes in Pairs

    Given a linked list, swap every two adjacent(相邻的) nodes and return its head. For example,Given 1-> ...

  8. [LeetCode]题解(python):024-Swap Nodes in Pairs

    题目来源: https://leetcode.com/problems/swap-nodes-in-pairs/ 题意分析: 给定一个链表,每两个相邻节点就行交换.比如1->2->3-&g ...

  9. LeetCode OJ:Swap Nodes in Pairs(成对交换节点)

    Given a linked list, swap every two adjacent nodes and return its head. For example,Given 1->2-&g ...

随机推荐

  1. Spring 并发事务的探究

    前言 在目前的软件架构中,不仅存在单独的数据库操作(一条SQL以内,还存在逻辑性的一组操作.而互联网软件系统最少不了的就是对共享资源的操作.比如热闹的集市,抢购的人群对同见商品的抢购由一位售货员来处理 ...

  2. 电信10兆指的是多少Mbps

    一般电信10兆(10Mbps)指的是:下载速度最大在1.25MB/s 1Mbps(兆位/秒)     =     0.125MB/S(兆字节/秒) 8Mbps(兆位/秒)     =     1MB/ ...

  3. 微信内置的浏览器window.location.href 跳转不兼容问题

    1.不兼容苹果手机---->>>>使用模拟触发a标签 <a id="alink" href="http://www.baidu.com&qu ...

  4. python爬虫常用之Scrapy 简述

    一.安装 pip install scrapy. 如果提示需要什么包就装什么包 有的包pip安装不起,需要自己下载whl文件进行安装. 二.基本的爬虫流程 通用爬虫有如下几步: 构造url --> ...

  5. C#二进制位算 权限

    关于权限管理,之前所做的都是一个权限对应一条数据,比方A页面有增删改查四个权限,那么用户在权限管理表中相对应AA页面有四条记录.后来改用二进制运算,发现省事很多. 首先说下位运算 熟悉一下操作符,懒得 ...

  6. C# .net 使用正则表达式去掉字符串中的数字

    /// <summary>/// 去掉字符串中的数字/// </summary>/// <param name="key"></param ...

  7. C#多线程学习一

    一.概述:C#支持多线程并行执行程序,一个线程有他单独的执行路径,能够与其他线程同时执行,一个程序是由一个单线程开始,该单线程由CLR(公共语言运行时)和操作系统创建而成,并具有多线程创建额外线程的功 ...

  8. 关于javascript的各种高宽

  9. redis 实现消息发布和订阅

    1,打开二个客户端机器 一个用于发布,一个用于接受 2,发布一个channel1 3,用另外一个客户端收听上面的客户端 4,当再次在发布的redis客户端 发布一个消息  其他所有订阅的客户端会自动收 ...

  10. 《LeetBook》leetcode题解(3):Longest Substring Without Repeating Characters[M]——哈希判断重复

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...