Codechef August Challenge 2019 Chef and Gordon Ramsay
[传送门]
题目即求所有的三元组,相对大小关系同 $p_1,p_2,p_3$。
题解说都很清楚,这里写一下过程整理一下思路。
如果我们枚举中间这个元素,那么就是统计子树内外有多少个大于这个数和小于这个数的个数。
假设$a_1$,$a_3$的$LCA$不是$a_2$,那么就是一个在$a_2$子树内一个在子树外。
设$S_u$, $B_u$分别为$u$子树内小于$u$和大于$u$的节点个数,$S_t$, $B_t$分别为整棵树小于$u$和大于$u$的节点个数。
当$p_2 = 1$时,对答案的贡献为$B_u \times (B_t - B_u)$
当$p_2 = 2$时,对答案的贡献为$B_u \times (S_t - S_u) + S_u \times (B_t - B_u)$
当$p_2 = 1$时,对答案的贡献为$S_u \times (S_t - S_u)$
当$a_1$和$a_3$的$LCA$是$a_2$时,枚举$u$的子节点。
设$S_v$为$u$的子节点$v$的子树中,小于$u$的节点个数,$B_v$为$u$的子节点$v$的子树中,大于$u$的节点个数。
当$p_2 = 1$时,对答案的贡献为$B_v \times (B_u - B_v)$
当$p_2 = 2$时,对答案的贡献为$S_v \times (B_u - B_v) + B_v \times (S_u - S_v)$
当$p_2 = 1$时,对答案的贡献为$S_v \times (S_u - S_v)$
这部分的贡献会被算两次,所以最后得除以二。
查子树内都多少节点大于/小于该节点的,题解用了dfs序+树状数组,但是对于第二部分求答案很麻烦。所以我用了线段树合并,不过会卡常,那么只求一遍小于的,再用子树的size减去这个值就得到大于的。
#include <bits/stdc++.h>
#define pii pair<int, int>
#define ll long long
using namespace std; namespace IO {
const int MAXSIZE = << ;
char buf[MAXSIZE], *p1, *p2;
#define gc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin), p1 == p2) ? EOF : *p1++)
template<class T>
inline void read(T &x) {
x = ; T f = ; char c = gc();
while (!isdigit(c)) { if (c == '-') f = -; c = gc(); }
while (isdigit(c)) x = x * + (c ^ ), c = gc();
x *= f;
}
char pbuf[ << ], *pp = pbuf;
inline void push(const char &c) {
if (pp - pbuf == << ) fwrite(pbuf, , << , stdout), pp = pbuf;
*pp++ = c;
}
inline void write(int x) {
static int sta[];
int top = ;
do {
sta[top++] = x % , x /= ;
} while (x);
while (top) push(sta[--top] + '');
}
} using namespace IO; const int N = 1e5 + ; int root[N], p[], n, sz[N];
vector<int> G[N]; struct Seg {
struct Tree {
int lp, rp, sum;
} tree[N * ];
int tol;
inline void clear() {
tol = ;
memset(tree, , sizeof(tree));
}
inline void pushup(int p) {
tree[p].sum = tree[tree[p].lp].sum + tree[tree[p].rp].sum;
}
void update(int &p, int l, int r, int pos) {
if (!p) p = ++tol;
if (l == r) {
tree[p].sum++;
return;
}
int mid = l + r >> ;
if (pos <= mid) update(tree[p].lp, l, mid, pos);
else update(tree[p].rp, mid + , r, pos);
pushup(p);
}
int merge(int p, int q, int l, int r) {
if (!p || !q) return p | q;
int u = ++tol;
int mid = l + r >> ;
tree[u].lp = merge(tree[p].lp, tree[q].lp, l, mid);
tree[u].rp = merge(tree[p].rp, tree[q].rp, mid + , r);
pushup(u);
return u;
}
int query(int p, int l, int r, int x, int y) {
if (x > y) return ;
if (!p) return ;
if (x <= l && y >= r) return tree[p].sum;
int mid = l + r >> ;
int ans = ;
if (x <= mid) ans += query(tree[p].lp, l, mid, x, y);
if (y > mid) ans += query(tree[p].rp, mid + , r, x, y);
return ans;
}
} seg; ll ans; inline void init() {
ans = ;
seg.clear();
for (int i = ; i <= n; i++) G[i].clear(), root[i] = ;
} void dfs(int u, int fa) {
seg.update(root[u], , n, u);
vector<pii> vec;
int su = , bu = ;
int st = u - , bt = n - u;
sz[u] = ;
for (auto v: G[u]) {
if (v == fa) continue;
dfs(v, u);
sz[u] += sz[v];
int sv = seg.query(root[v], , n, , u - ), bv = sz[v] - sv;
su += sv, bu += bv;
vec.push_back(pii(sv, bv));
root[u] = seg.merge(root[u], root[v], , n);
}
if (p[] == )
ans += 1LL * bu * (bt - bu);
else if (p[] == )
ans += 1LL * bu * (st - su) + 1LL * su * (bt - bu);
else
ans += 1LL * su * (st - su);
ll res = ;
for (auto pp: vec) {
if (p[] == )
res += 1LL * pp.second * (bu - pp.second);
else if (p[] == )
res += 1LL * pp.first * (bu - pp.second) + 1LL * pp.second * (su - pp.first);
else
res += 1LL * pp.first * (su - pp.first);
}
ans += res / ;
} int main() {
// freopen("in.txt", "r", stdin);
int T;
read(T);
while (T--) {
read(n);
init();
for (int i = ; i < ; i++) read(p[i]);
for (int i = ; i < n; i++) {
int u, v;
read(u), read(v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(, );
printf("%lld\n", ans);
}
return ;
}
Codechef August Challenge 2019 Chef and Gordon Ramsay的更多相关文章
- Codechef August Challenge 2019 Division 2
Preface 老年菜鸡终于开始打CC了,由于他太弱了所以只能打Div2 因为台风的原因challenge并没有写,所以水了个Rank7 A Football SB模拟题不解释 #include< ...
- Codechef August Challenge 2018 : Chef at the River
传送门 (要是没有tjm(Sakits)的帮忙,我还真不知道啥时候能做出来 结论是第一次带走尽可能少的动物,使未带走的动物不冲突,带走的这个数量就是最优解. 首先这个数量肯定是下界,更少的话连第一次都 ...
- 【CodeChef】August Challenge 2019 Div2 解题报告
点此进入比赛 \(T1\):Football(点此看题面) 大致题意: 求\(max(20a_i-10b_i,0)\). 送分题不解释. #include<bits/stdc++.h> # ...
- Codechef April Challenge 2019 游记
Codechef April Challenge 2019 游记 Subtree Removal 题目大意: 一棵\(n(n\le10^5)\)个结点的有根树,每个结点有一个权值\(w_i(|w_i\ ...
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries
https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef and Hamming Distance of arrays
https://www.codechef.com/DEC17/problems/CHEFHAM #include<cstdio> #include<cstring> #incl ...
- CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And his Cake
https://www.codechef.com/DEC17/problems/GIT01 #include<cstdio> #include<algorithm> using ...
- CodeChef April Challenge 2019题解
传送门 \(Maximum\ Remaining\) 对于两个数\(a,b\),如果\(a=b\)没贡献,所以不妨假设\(a<b\),有\(a\%b=a\),而\(b\%a<a\).综上, ...
- Codechef October Challenge 2019 Division 1
Preface 这次CC难度较上两场升高了许多,后面两题都只能借着曲明姐姐和jz姐姐的仙气来做 值得一提的是原来的F大概需要大力分类讨论,结果我写了一大半题目就因为原题被ban了233 最后勉强涨了近 ...
随机推荐
- DFS or BFS --- 连通块
Oil Deposits Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64 Descrip ...
- Java计算工作日的工具类
有时候需要根据工作日计算指定的日期,也就是需要排除周六日. 1. 初版代码如下: package cn.xm.exam.utils; import java.util.Calendar; impor ...
- STM8L独立看门狗IWDG
简单扼要 void IWDG_Init(void)//初始化 { IWDG->KR = 0xcc;//启动IWDG IWDG->KR = 0x55;//解除PR及RLR的写保护 IWDG- ...
- apache添加ssl协议实现用户认证
目标 1对服务器的访问由http改为https, 2仅有证书的客户端可以访问服务器, 3.通过服务器端的配置,可以停用某个客户端的证书. 一 Apache服务器相关配置: 在../apache/con ...
- Fiddler手机抓包不完全记录
准备工作: 1.必须确保安装fiddler的电脑和手机在同一个wifi环境下 备注:如果电脑是笔记本当然最好;如果电脑用的是台式机,可以安装一个随身wifi,来确保台式机和手机在同一wifi环境下 ...
- TRIO-basic指令--CAM
大家好,今天更新TRIO的运动指令CAM(也就是CAM函数),CAM指令是控制器直接发送编码器脉冲形成的运动曲线,比如:正弦,余弦曲线,根据自己的精度需求进行描点,但并不一定点数越多精度就越高,以实际 ...
- MySQL5.6.17 绿色版 安装配置
安装篇: 下载完成之后,用解压工具解压到没有中文.空格的文件夹下,解压后的显示如图: 个人建议把解压后的文件夹重命名,如果有中文去掉中文,便于自己理解使用,如图: 打开重命名之后的文件夹,找到mysq ...
- 推荐算法之E&E
一.定义 E&E就是探索(explore)和利用(exploit). Exploit:基于已知最好策略,开发利用已知具有较高回报的item(贪婪.短期回报),对于推荐来讲就是用户已经发现的兴趣 ...
- drf之组件(认证、权限、排序、过滤、分页等)和xadmin、coreapi
认证Authentication 可以在配置文件中配置全局默认的认证方案 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_fr ...
- 关于银企直连中银行通信类 配置篇 EPIC_PROC
简单介绍:SAP银行企业直连,英文全称:Electronic Payment Integration(For China),简称EPIC,是SAP中国为本地化的需求开发的一款产品,以银企直连为支撑,主 ...