P3899 [湖南集训]更为厉害

对于上述条件,满足深度限制即可。

Code1

线段树合并暴力合并子树

1.80s / 90.65MB / 1.82KB C++17

#include<bits/stdc++.h>using namespace std;
using ll=long long;
constexpr int N=300010;
int h[N],e[2*N],ne[2*N],idx;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
int n,q;
struct node
{int l,r;ll v;
}tree[N*40];
int root[N],cnt;
void insert(int &u,int l,int r,int pos,ll v)
{if(!u) u=++cnt;if(l==r) return tree[u].v+=v,void();int mid=l+r>>1;if(pos<=mid) insert(tree[u].l,l,mid,pos,v);elseinsert(tree[u].r,mid+1,r,pos,v);tree[u].v=tree[tree[u].l].v+tree[tree[u].r].v;
}
ll query(int u,int l,int r,int L,int R)
{if(!u) return 0ll;if(L<=l&&r<=R) return tree[u].v;int mid=l+r>>1;ll v=0;if(L<=mid)v+=query(tree[u].l,l,mid,L,R);if(R>mid)v+=query(tree[u].r,mid+1,r,L,R);return v;
}
int merge(int x,int y)
{if(!x||!y) return x+y;int u=++cnt;tree[u].v=tree[x].v+tree[y].v;tree[u].l=merge(tree[x].l,tree[y].l);tree[u].r=merge(tree[x].r,tree[y].r);return u;
}int dep[N],sz[N];void dfs(int u,int fa)
{dep[u]=dep[fa]+1;sz[u]=1;for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==fa) continue;dfs(v,u);sz[u]+=sz[v];root[u]=merge(root[u],root[v]);}insert(root[u],1,n,dep[u],sz[u]-1);
}int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n>>q;memset(h,-1,sizeof h);for(int i=1;i<n;i++){int u,v;cin>>u>>v;add(u,v),add(v,u);}dfs(1,0);while(q--){int p,k;cin>>p>>k;ll ans=0;ans+=1ll*min(k,dep[p]-1)*(sz[p]-1);ans+=query(root[p],1,n,dep[p]+1,dep[p]+k);cout<<ans<<'\n';}return 0;
}

Code2

长链剖分

1.51s / 48.94MB / 1.60KB C++17

#include<bits/stdc++.h>using namespace std;
using ll=long long;
constexpr int N=300010;
int h[N],e[2*N],ne[2*N],idx;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
ll ans[N];
int n,m;
int ht[N],son[N],sz[N],dep[N];
void dfs1(int u,int fa)
{sz[u]=1;dep[u]=dep[fa]+1;for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==fa) continue;dfs1(v,u);sz[u]+=sz[v];if(ht[son[u]]<ht[v]) son[u]=v;}ht[u]=ht[son[u]]+1;
}
ll pool[N];
ll *f[N],*now=pool;
ll tag[N];
vector<pair<int,int>> q[N];
void dfs2(int u,int fa)
{if(son[u]){f[son[u]]=f[u]+1;dfs2(son[u],u);tag[u]=tag[son[u]]+sz[son[u]]-1;}for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==fa||v==son[u]) continue;f[v]=now;now+=ht[v];dfs2(v,u);tag[u]+=tag[v]+sz[v]-1;for(int j=1;j<ht[v];j++)f[u][j]+=f[v][j-1];//+tag[v]+sz[v]-1;}f[u][0]-=tag[u];for(auto [k,id]:q[u]) ans[id]=1ll*min(dep[u]-1,k)*(sz[u]-1)+f[u][min(k,ht[u]-1)]+tag[u];
}int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n>>m;memset(h,-1,sizeof h);for(int i=1;i<n;i++){int u,v;cin>>u>>v;add(u,v),add(v,u);}for(int i=1;i<=m;i++){int p,k;cin>>p>>k;q[p].push_back({k,i});}dfs1(1,0);f[1]=now;now+=ht[1];dfs2(1,0);for(int i=1;i<=m;i++) cout<<ans[i]<<'\n';return 0;
}

Code3

主席树二维数点

2.58s / 107.27MB / 1.85KB C++17

#include<bits/stdc++.h>using namespace std;
using ll=long long;
constexpr int N=300010;
int h[N],e[2*N],ne[2*N],idx;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
int n,q;
struct node
{int l,r;ll v;
}tree[N*40];
int rt[N],cnt;
void insert(int &u,int o,int l,int r,int pos,ll v)
{tree[u=++cnt]=tree[o];tree[u].v+=v;if(l==r) return;int mid=l+r>>1;if(pos<=mid) insert(tree[u].l,tree[o].l,l,mid,pos,v);elseinsert(tree[u].r,tree[o].r,mid+1,r,pos,v);
}
ll query(int u,int l,int r,int L,int R)
{if(!u) return 0ll;if(L<=l&&r<=R) return tree[u].v;int mid=l+r>>1;ll v=0;if(L<=mid)v+=query(tree[u].l,l,mid,L,R);if(R>mid)v+=query(tree[u].r,mid+1,r,L,R);return v;
}int dep[N],sz[N];
int L[N],timestamp,R[N];void dfs1(int u,int fa)
{L[u]=++timestamp;dep[u]=dep[fa]+1;sz[u]=1;for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==fa) continue;dfs1(v,u);sz[u]+=sz[v];}R[u]=timestamp;}
void dfs2(int u,int fa)
{insert(rt[L[u]],rt[L[u]-1],1,n,dep[u],sz[u]-1);for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==fa) continue;dfs2(v,u);}
}
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n>>q;memset(h,-1,sizeof h);for(int i=1;i<n;i++){int u,v;cin>>u>>v;add(u,v),add(v,u);}dfs1(1,0);dfs2(1,0);while(q--){int u,k;cin>>u>>k;ll ans=0;ans+=1ll*min(k,dep[u]-1)*(sz[u]-1);ans+=query(rt[R[u]],1,n,dep[u]+1,dep[u]+k)-query(rt[L[u]-1],1,n,dep[u]+1,dep[u]+k);cout<<ans<<'\n';}return 0;
}

本质上线段树合并是通过该节点的子树构建当前树直接得到子树信息,而主席树是通过转化dfs序构建前缀树,通过作差得到子树的信息。

如果某些信息不支持做差得到,那么主席树的做法将失效,而线段树合并仍然适用

P3899 [湖南集训]更为厉害(线段树合并、长链剖分、二维数点)相关推荐

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

    P3899 [湖南集训]谈笑风生 给定一颗以111号节点为根的树,如果a≠ba \neq ba​=b,且aaa是bbb的祖先,则aaa比bbb更厉害,如果a≠ba \neq ba​=b,且dis( ...

  2. [湖南集训]更为厉害 树上主席树-以树深度为下下标建立主席树

    题意题解: 首先对于树上某个点a来说,假设点b是a的祖先(也就是在a的上面),那么答案很好计算,也就是min(k,dep[a]−1)∗(size[a]−1)min(k,dep[a]-1)*(size[ ...

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

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

  4. 洛谷 - P3899 [湖南集训]谈笑风生(dfs序+主席树/二维数点)

    题目链接:点击查看 题目大意:设 TTT 为一棵有根树,我们做如下的定义: 设 aaa 和 bbb 为 TTT 中的两个不同节点.如果 aaa 是 bbb 的祖先,那么称"aaa 比 bbb ...

  5. P3899 [湖南集训]谈笑风生 主席树解决二维数点

    传送门 文章目录 题意: 思路: 题意: 思路: 由于a,ba,ba,b都比ccc厉害,那么a,ba,ba,b一定是某个是某个的祖先.那么就分为两种情况了: (1)(1)(1) bbb在aaa上面,约 ...

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

    P3899 [湖南集训]谈笑风生 题目描述 Solution 我们考虑离线询问,将询问放在相对应的子树ppp中计算答案. 显然a,b,ca,b,ca,b,c的位置关系有两种情况: bbb是aaa的祖先 ...

  7. 线段树合并与分裂维护树上最长上升子序列 + 点分治删点 ---- 2021 牛客多校第一场 C - Cut the tree(详解)

    题目大意: 给你一个树,树上每个点都有一个权值valnodeval_{node}valnode​,路径(u,v)(u,v)(u,v) 上所有点按顺序有序序列,令f(u,v)f(u,v)f(u,v)是这 ...

  8. 线段树分裂与合并 ---- 树上差分 P4556 [Vani有约会]雨天的尾巴 /【模板】线段树合并

    题目链接 解题思路: 首先题目是对u,vu,vu,v这两条路径上面添加一个zzz,然后运用树上点的差分思想,对于分发路径u,vu,vu,v,我们在uuu上+1+1+1,在vvv上+1+1+1,在lca ...

  9. 【线段树合并】解题报告:luogu P4556雨天的尾巴 (树上对点差分 + 动态开点 + 线段树合并)线段树合并模板离线/在线详解

    题目链接:雨天的尾巴 本题本身是一个非常简单的一道树上差分的模板题,但是由于变态的数据范围,我们直接用数组是存不下的(本来使用一颗普通的线段树直接维护最大值即可.但是本题的空间只有128MB,直接按照 ...

最新文章

  1. python 进度条_Python小程序系列——动态进度条(1)
  2. 不同stm32f103芯片内部外设资源
  3. NSArray和NSMutableArray
  4. Hadoop MapReduce容错性分析
  5. “苹果光环”褪色后,瑞声靠什么坐稳头把交椅?
  6. Codeforces 362E Petya and Pipes 费用流建图
  7. Flickr30k图像标注数据集下载及使用方法(转载的,备忘)
  8. java io流(字符流) 文件打开、读取文件、关闭文件
  9. P3272 [SCOI2011]地板(插头DP)
  10. 练习2.13 不用库函数,写一个高效计算ln N的C函数
  11. iOS-多线程 ,整理集锦,多种线程的创建
  12. Java安全 – JCE (Blowfish算法报错)
  13. mysql exporter怎么配置_mysqld_exporter的源码分析和定制化(单个mysqld_exporter监控多个数据库实例)...
  14. java给mongo数组添加_如何使用具有新值的java在mongodb中的现有集合中追加现有数组...
  15. [转载] 3 idiots
  16. cmder 下载与简单设置
  17. 国内主要OTT平台背后的那些CDN服务商
  18. python爬取豆瓣电影250_利用Python爬取豆瓣TOP250的电影
  19. Scrapy框架基础了解
  20. 只有快递单号,怎样查询物流进度查看正在派件的单号

热门文章

  1. mysql 5.7.17 源码安装_mysql5.7.17源码安装
  2. sql同时向两个表插入数据_SQL入门-数据库和客户端的安装,表的创建和数据插入...
  3. linux删除第二次出现的字符,linux下 怎样删除文件名中包含特殊字符的文件
  4. c语言修仙受控可看吗,强推三本神奇到爆的小说,c语言修仙,程序员与修真会擦出什么火花...
  5. leetcode84. 柱状图中最大的矩形
  6. 一张网页带你了解中秋节的前世今生
  7. Java面向对象编程(中级)
  8. [Java基础]增强for循环
  9. 使用pdf.js来预览pdf文件_适用于Dynamics365与PowerApps的注释预览组件
  10. 华为任职资格_看了华为的任职资格体系,你就明白员工为啥这么拼?