【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)
题目链接
容易发现\(a,b,c\)肯定是在一条直链上的。
定义\(size(u)\)表示以\(u\)为根的子树大小(不包括\(u\))
分两种情况,
1、\(b\)是\(a\)的祖先,对答案的贡献是
\]
显然是可以直接算的。
2、\(b\)是\(a\)的孩子,对答案的贡献为
\]
后半段就可以主席树来维护了。
下标为深度,值为\(\sum size\),因为同一子树内\(dfs\)序是连续的,就像树剖那样用主席树维护就好了。
(为什么我总是不记得开\(long long\)?)
#include <cstdio>
typedef long long ll;
int s; char ch;
inline int read(){
s = 0; ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
return s;
}
inline void Chkmax(int &a, int b){
if(b > a) a = b;
}
inline int min(int a, int b){
return a > b ? b : a;
}
const int MAXN = 300010;
const int MAXMLOGN = 60000010;
int num, maxdeep, cnt, ID, n, m, a, b;
int head[MAXN], deep[MAXN], dfn[MAXN], pos[MAXN], root[MAXN], size[MAXN];
struct Tree{
ll val;
int lc, rc;
}t[MAXMLOGN];
inline void pushup(int now){
t[now].val = t[t[now].lc].val + t[t[now].rc].val;
}
int build(int l, int r){
int id = ++cnt;
if(l == r) return id;
int mid = (l + r) >> 1;
t[id].lc = build(l, mid);
t[id].rc = build(mid + 1, r);
return id;
}
int insert(int now, int l, int r, int x, int y){
int id = ++cnt; t[id] = t[now];
if(l == r){ t[id].val += y; return id; }
int mid = (l + r) >> 1;
if(x <= mid) t[id].lc = insert(t[now].lc, l, mid, x, y);
else t[id].rc = insert(t[now].rc, mid + 1, r, x, y);
pushup(id);
return id;
}
ll query(int p, int q, int l, int r, int wl, int wr){
if(r < wl || l > wr) return 0;
if(l >= wl && r <= wr) return t[q].val - t[p].val;
int mid = (l + r) >> 1; ll ans = 0;
ans += query(t[p].lc, t[q].lc, l, mid, wl, wr);
ans += query(t[p].rc, t[q].rc, mid + 1, r, wl, wr);
return ans;
}
struct Edge{
int next, to;
}e[MAXN << 1];
inline void Add(int from, int to){
e[++num].to = to; e[num].next = head[from]; head[from] = num;
e[++num].to = from; e[num].next = head[to]; head[to] = num;
}
int dfs(int u, int fa){
Chkmax(maxdeep, deep[u] = deep[fa] + 1);
dfn[u] = ++ID;
for(int i = head[u]; i; i = e[i].next)
if(e[i].to != fa)
size[u] += dfs(e[i].to, u);
return size[u] + 1;
}
int main(){
n = read(); m = read();
for(int i = 1; i < n; ++i)
Add(read(), read());
dfs(1, 0);
for(int i = 1; i <= n; ++i)
pos[dfn[i]] = i;
root[0] = build(1, maxdeep);
for(int i = 1; i <= n; ++i)
root[i] = insert(root[i - 1], 1, maxdeep, deep[pos[i]], size[pos[i]]);
for(int i = 1; i <= m; ++i){
a = read(); b = read();
printf("%lld\n", (ll)min(deep[a] - 1, b) * size[a] + query(root[dfn[a] - 1], root[dfn[a] + size[a]], 1, maxdeep, deep[a] + 1, deep[a] + b));
}
return 0;
}
【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)的更多相关文章
- 洛谷P3899 [湖南集训]谈笑风生(线段树合并)
题意 题目链接 Sol 线段树合并板子题,目前我看到两种写法,分别是这样的. 前一种每次需要新建一个节点,空间是\(O(4nlogn)\) 后者不需要新建,空间是\(O(nlogn)\)(面向数据算空 ...
- [Luogu P3899] [湖南集训]谈笑风生 (主席树)
题面 传送门:https://www.luogu.org/problemnew/show/P3899 Solution 你们搞的这道题啊,excited! 这题真的很有意思. 首先,我们可以先理解一下 ...
- P3899 [湖南集训]谈笑风生 主席树
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...
- luogu P3899 [湖南集训]谈笑风生 线段树合并
Code: #include<bits/stdc++.h> #define maxn 300002 #define ll long long using namespace std; vo ...
- 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生
题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...
- 洛谷P2617 Dynamic Ranking(主席树,树套树,树状数组)
洛谷题目传送门 YCB巨佬对此题有详细的讲解.%YCB%请点这里 思路分析 不能套用静态主席树的方法了.因为的\(N\)个线段树相互纠缠,一旦改了一个点,整个主席树统统都要改一遍...... 话说我真 ...
- 洛谷P4587 神秘数 [FJOI2016] 主席树
正解:主席树 解题报告: 先放下传送门QAQ 首先可以先思考如果只有一组询问,怎么解决 可以这么想,最开始一个数也麻油的时候能表示的最大的数是0嘛 然后先排个序,按顺序每次新加入一个数x,设加入这个数 ...
- 2018.09.14 洛谷P3567 [POI2014]KUR-Couriers(主席树)
传送门 简单主席树啊. 但听说有随机算法可以秒掉%%%(本蒟蒻并不会) 直接维护值域内所有数的出现次数之和. 当这个值不大于区间总长度的一半时显然不存在合法的数. 这样在主席树上二分查值就行了. 代码 ...
- 2018.07.07 洛谷 P3939 数颜色(主席树)
P3939 数颜色 题目背景 大样例下发链接:http://pan.baidu.com/s/1c0LbQ2 密码:jigg 题目描述 小 C 的兔子不是雪白的,而是五彩缤纷的.每只兔子都有一种颜色,不 ...
- 洛谷P3168 [CQOI2015]任务查询系统 [主席树,差分]
题目传送门 任务查询系统 题目描述 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任 ...
随机推荐
- css那些事儿4 背景图像
background:背景颜色,图像,平铺方式,大小,位置 能够显示背景区域即为盒子模型的填充和内容部分,其中背景图像将会覆盖背景颜色.常见的水平或垂直渐变颜色背景通常使用水平或垂直渐变的背景图像在水 ...
- 手把手教你写Kafka Streams程序
本文从以下四个方面手把手教你写Kafka Streams程序: 一. 设置Maven项目 二. 编写第一个Streams应用程序:Pipe 三. 编写第二个Streams应用程序:Line Split ...
- matlab怎么选取excel的特定列构成数组
例如:
- TScreen 类 - 通过 Screen 更换光标
//更换窗体或某个控件的光标可以不通过 Screen 对象, 譬如: begin Self.Cursor := crAppStart; Panel1.Cursor := crHandPoint ...
- window.navigator.standalone 检测iOS WebApp是否运行在全屏模式
iOS上的Safari浏览器可以让Web应用程序全屏显示,以取得类似本地应用的显示效果.但是这需要用户把Web应用程序的图标添加到主屏幕才可以.作为开发者,为了更好的显示效果,我们可能希望自己开发的W ...
- Gevent-自动挡切换
Gevent: Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程. G ...
- bzoj 3132: 上帝造题的七分钟 (二维树状数组)
推推公式,最后变成四个东西的前缀和 然后不知道为什么一直wa,数据在本地测是没有错的& 好心的管理员还给了某位p党大神a了的代码,感人肺腑(虽然还是没发现到底我的程序是问题) var f1,f ...
- 洛谷4643:【模板】动态dp——题解
https://www.luogu.org/problemnew/show/P4643 很妙……让我重新又看了一遍猫锟的WC课件. 推荐一个有markdown神犇题解:https://www.cnbl ...
- lamp 源码安装
#!/bin/bash #description:mysql-.tar apache2.4.23 php5.6.27 function check_ok(){ ] then echo "-- ...
- requireJs使用方法项目实例
首先,定义 main.js 和 事件处理的公共 js main.js 主要是定义引用名称和路径的对应关系 事件绑定模块: 写jsp页面: jsp中先引入 require.js 和 main.js 然 ...