BZOJ 3653权限题。

这题方法很多,但我会的不多……

给定了$a$,我们考虑讨论$b$的位置:

1、$b$在$a$到根的链上,那么这样子$a$的子树中的每一个结点(除了$a$之外)都是可以成为$c$的,答案就是$min(dep_a - 1, k) * (siz_a - 1)$。

2、$b$在$a$的子树中,这样子$c$的位置受$b$限制,这样子的答案就是$\sum_{x}(siz_x - 1) \ (x \in subtree(a), dep_x - dep_a \leq k)$。

第一个直接算就好,第二个可以用主席树维护出来,具体方法就和CF893F Subtree Minimum Query一样,按照深度建一棵线段树,然后查询的时候只要看一下对应深度的子树中和是多少就可以了。

所以在线的时候就可以回答了。

时间复杂度$O((n + q) logn)$。

Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll; const int N = 3e5 + ; int n, qn, tot = , head[N], bel[N];
int dfsc = , dep[N], siz[N], id[N]; struct Edge {
int to, nxt;
} e[N << ]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} struct SortNode {
int val, pos; friend bool operator < (const SortNode &x, const SortNode &y) {
return x.val < y.val;
} } so[N]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline int min(int x, int y) {
return x > y ? y : x;
} inline int max(int x, int y) {
return x > y ? x : y;
} inline void chkMax(int &x, int y) {
if(y > x) x = y;
} void dfs(int x, int fat, int depth) {
dep[x] = depth, siz[x] = , id[x] = ++dfsc;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fat) continue;
dfs(y, x, depth + );
siz[x] += siz[y];
}
} namespace SegT {
struct Node {
int lc, rc;
ll sum;
} s[N * ]; int root[N], nodeCnt = ; #define lc(p) s[p].lc
#define rc(p) s[p].rc
#define sum(p) s[p].sum
#define mid ((l + r) >> 1) void ins(int &p, int l, int r, int x, ll v, int pre) {
s[p = ++nodeCnt] = s[pre];
sum(p) += v;
if(l == r) return; if(x <= mid) ins(lc(p), l, mid, x, v, lc(pre));
else ins(rc(p), mid + , r, x, v, rc(pre));
} ll query(int p, int l, int r, int x, int y) {
if(x > y) return 0LL;
if(x <= l && y >= r) return sum(p); ll res = 0LL;
if(x <= mid) res += query(lc(p), l, mid, x, y);
if(y > mid) res += query(rc(p), mid + , r, x, y); return res;
} } using namespace SegT; int main() {
// freopen("2.in", "r", stdin);
// freopen("my.out", "w", stdout); read(n), read(qn);
for(int x, y, i = ; i < n; i++) {
read(x), read(y);
add(x, y), add(y, x);
}
dfs(, , ); for(int i = ; i <= n; i++)
so[i].val = dep[i], so[i].pos = i;
sort(so + , so + + n); int maxd = ;
for(int i = ; i <= n; i++) {
ins(root[i], , n, id[so[i].pos], 1LL * (siz[so[i].pos] - ), root[i - ]);
chkMax(maxd, so[i].val);
bel[so[i].val] = i;
} for(int x, k; qn--; ) {
read(x), read(k);
ll res = 1LL * min(dep[x] - , k) * (siz[x] - );
res += query(root[bel[min(maxd, dep[x] + k)]], , n, id[x] + , id[x] + siz[x] - );
printf("%lld\n", res);
} return ;
}

Luogu 3899 [湖南集训]谈笑风生的更多相关文章

  1. 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生

    题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...

  2. luogu P3899 [湖南集训]谈笑风生

    传送门 nmyzd,mgdhls,bnmbzdgdnlql,a,wgttxfs 对于一个点\(a\),点\(b\)只有可能是他的祖先或者在\(a\)子树里 如果点\(b\)是\(a\)祖先,那么答案为 ...

  3. luogu P3899 [湖南集训]谈笑风生 线段树合并

    Code: #include<bits/stdc++.h> #define maxn 300002 #define ll long long using namespace std; vo ...

  4. [Luogu P3899] [湖南集训]谈笑风生 (主席树)

    题面 传送门:https://www.luogu.org/problemnew/show/P3899 Solution 你们搞的这道题啊,excited! 这题真的很有意思. 首先,我们可以先理解一下 ...

  5. bzoj 3653 [湖南集训]谈笑风生

    题目描述 设 T 为一棵有根树,我们做如下的定义: • 设 a 和 b 为 T 中的两个不同节点.如果 a 是 b 的祖先,那么称"a 比 b 不知道高明到哪里去了". • 设 a ...

  6. P3899 [湖南集训]谈笑风生

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P38 ...

  7. 洛谷P3899 [湖南集训]谈笑风生(线段树合并)

    题意 题目链接 Sol 线段树合并板子题,目前我看到两种写法,分别是这样的. 前一种每次需要新建一个节点,空间是\(O(4nlogn)\) 后者不需要新建,空间是\(O(nlogn)\)(面向数据算空 ...

  8. 【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)

    题目链接 容易发现\(a,b,c\)肯定是在一条直链上的. 定义\(size(u)\)表示以\(u\)为根的子树大小(不包括\(u\)) 分两种情况, 1.\(b\)是\(a\)的祖先,对答案的贡献是 ...

  9. P3899 [湖南集训]谈笑风生 主席树

    #include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...

随机推荐

  1. html页面中如何设置当光标移到一个固定区域时其形状变成手型,移出时恢复

    在除了IE6的情况下,可以通过CSS的:hover伪类来实现: 假如你想设定的固定区域为:<div id="test"></div>,那么只需要在CSS样式 ...

  2. Ubantu中安装sublime

    Sublime-text-3的安装步骤   添加Sublime-text-3软件包的软件源 sudo add-apt-repository ppa:webupd8team/sublime-text-3 ...

  3. Android开发SQLite数据库的创建

    package com.example.db; import android.content.Context; import android.database.sqlite.SQLiteDatabas ...

  4. android生命周期参考

    public class ActivityDemo extends Activity { private static final String TAG = "ActivityDemo&qu ...

  5. 使用ajax提交form表单,formData

    http://www.cnblogs.com/zhuxiaojie/p/4783939.html formDatahttps://developer.mozilla.org/zh-CN/docs/We ...

  6. jquery 实现点击颜色切换

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  7. FPGA论剑(续)

    25年之后,第二次华山论剑之时,天下第一的王重阳已然仙逝,郭靖少年英杰刚过二十岁,接东邪黄药师.北丐洪七公300招不败,二人默认郭靖天下第一.南帝段智兴因为出家,法号“一灯”,早已看破名利,故没有参加 ...

  8. sed命令常见用法

    sed -n 'num1p' file 选出行号为num1的行sed -n 'num1,num2p' file 选出num1~num2行sed -n 'num1,$p' file 选出num1行到文件 ...

  9. PL/Sql developer安装,设置

    安装PL/Sql developer,和安装出现错误(oracle client not properly installed),pl/sql中文乱码 下载安装plsql_dev(文末有64位的百度云 ...

  10. 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...