BZOJ 2851: 极限满月 虚树 or 树链的并
2851: 极限满月
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 170 Solved: 82
[Submit][Status][Discuss]
Description

Input
Output
Sample Input
0
1 1
1 1
1 2
2 2 3
0
2 2 6
3
2 2 3
2 3 5
2 4 5
Sample Output
3
4
HINT
/*对于100% 的数据,1 <= n, m <= 50000,1 <= 10^9,-10^9 <= a, b, x, y <= 10^9。*/
[Discuss]里的正确数据范围:
n<=200000 m<=200000
A集合元素总个数<=300000
输入总数<=2500000
Source
想法:
如果把Bi当成红点,i当成蓝点,B0为一个虚红点,边V->U为U∈V。因为"a∈Ak=>a<k",所以每个Bi(i>0)红点只会连一个蓝点与一个红点。因此红点构成一棵树。
显然易见,Bi所连的红点为{Bj|j∈Ai}的lca。于是答案变成求集合{S}中所有红点所包含蓝点的并的大小。因为每个点蓝点只会被一个红点连边,所以可以把蓝点捆在该红点上,答案就变成统计{S}中所有红点的祖先并(除去B0虚红点)的大小。于是可以使用虚树或者树链的并解决。
复杂度O((∑|A|+∑|S|)logn).
细节:你会发现建红点树的过程是动态加点的在线求lca的过程。可以用倍增(仅支持加点)或LCT(支持加点删点换根....)解决。
#include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm> typedef long long ll;
const int N();
struct Node
{
int nd,nx;
}bot[N];
int tot,first[N],depth[N],dfn[N],cnt;
void add(int a,int b){bot[++tot]=(Node){b,first[a]};first[a]=tot;}
int F[][N],logg;
int n,m,h[N],S;
std::vector<int>A[N];int sz,x;
template<class T>void read(T&x)
{
x=;bool f=;char c=getchar();
while((c<''||c>'')&&c!='-')c=getchar();if(c=='-')f=,c=getchar();
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
x=f?-x:x;
}
void swap(int &x,int &y){if(x==y)return;x^=y;y^=x;x^=y;}
int lca(int a,int b)
{
if(depth[a]<depth[b])swap(a,b);
// fprintf(stderr,"a:%d b:%d\b",a,b);
for(int k=depth[a]-depth[b],j=;k;k>>=,j++)
if(k&)a=F[j][a];
// fprintf(stderr,"a:%d b:%d\b",a,b);
if(a==b)return a;
for(int j=logg;F[][a]!=F[][b];j--)
if(F[j][a]!=F[j][b])a=F[j][a],b=F[j][b];
return F[][a];
}
void relax(int x)
{
for(int j=;j<=logg&&F[j-][x];j++)
F[j][x]=F[j-][ F[j-][x] ];
}
namespace GetTree
{
void init()
{
read(n);
for(int i=;i<=n;i++)
{
read(sz);
while(sz--) read(x),A[i].push_back(x);
std::sort(A[i].begin(),A[i].end());
}
}
void build()
{
logg=log2(n);
for(int i=,now;i<=n;i++)
{
now=n+;
if(A[i].size())
{
now=A[i][];
for(int v=,sz=A[i].size();v<sz;v++)
{
// fprintf(stderr,"now:%d\n",now);
now=lca(now,A[i][v]);
// fprintf(stderr,"A:%d\n",A[i][v]);
}
}
// fprintf(stderr,"now:%d\n",now);
F[][i]=now;depth[i]=depth[now]+;
add(now,i);
relax(i);
}
}
void DFS(int x)
{
dfn[x]=++cnt;
for(int v=first[x];v;v=bot[v].nx) DFS(bot[v].nd);
}
void run()
{
init();
build();
DFS(n+);
}
} bool cmp(int a,int b){return dfn[a]<dfn[b];}
void total()
{
std::sort(h+,h+S+,cmp);
int ans=;
for(int i=,t;i<=S;i++)
{
ans+=depth[h[i]];
// fprintf(stderr,"ans:%d\n",ans);
if(i>)
{
t=lca(h[i-],h[i]);
ans-=depth[t];
}
}
printf("%d\n",ans);
} int main()
{
// freopen("C.in","r",stdin);
GetTree::run();
read(m);
for(int i=;i<=m;i++)
{
read(S);
for(int j=;j<=S;j++) read(h[j]);
total();
}
return ;
}
BZOJ 2851: 极限满月 虚树 or 树链的并的更多相关文章
- [BZOJ 3489] A simple rmq problem 【可持久化树套树】
题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...
- [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】
题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...
- bzoj 1901: Zju2112 Dynamic Rankings(树套树)
1901: Zju2112 Dynamic Rankings 经典的带改动求区间第k小值问题 树套树模板,我是用的线段树套splay实现的,并且用的数组模拟的,所以可能空间略大,bzoj过了,zoj过 ...
- BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)
BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- bzoj 4031: 小Z的房间 矩阵树定理
bzoj 4031: 小Z的房间 矩阵树定理 题目: 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时 ...
- [BZOJ 1535] [Luogu 3426]SZA-Template (KMP+fail树+双向链表)
[BZOJ 1535] [Luogu 3426]SZA-Template (KMP+fail树+双向链表) 题面 Byteasar 想在墙上涂一段很长的字符,他为了做这件事从字符的前面一段中截取了一段 ...
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6050 Solved: 2007[Submit][Sta ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
随机推荐
- AutoHotkey常用配置
; 开发常用 ^e:: run D:\soft\java\MyEclipse for Spring 2014\myeclipseforspring.exe return ^d:: run D:\sof ...
- gitHub上传代码
首先进入github官网注册一个帐号 00.png 注册完帐号之后创建一个项目 01.png 设置创建项目的信息 02.png 创建项目完之后复制项目的地址,以供后面下载项目使用 03.png 在桌面 ...
- Deep Learning - Install the Development Environment
WLS(Windows Subsystem for Linux) Base WLS Installation Guide Initializing a newly installed distro W ...
- LaTeX 语法
MathJax是什么? MathJax是一个开源JavaScript库.它支持LaTeX.MathML.AsciiMath符号,可以运行于所有流行浏览器上. LaTeX是什么? LaTeX(LATEX ...
- poj 2049(二分+spfa判负环)
poj 2049(二分+spfa判负环) 给你一堆字符串,若字符串x的后两个字符和y的前两个字符相连,那么x可向y连边.问字符串环的平均最小值是多少.1 ≤ n ≤ 100000,有多组数据. 首先根 ...
- duliu——思维+线段树
题目 [题目描述]小 `D` 喜欢出毒瘤题毒人.当然,他的毒瘤更多体现在若干个难题组合在同一场比赛时.小 `D` 脑中有 $n$ 个毒瘤题 idea,第 $i$ 个的毒值为$d_i$.当第 $i$ 个 ...
- express使用session会话
前几周在学习nodejs基础,发现nodejs没有session会话变量,导致登录注册实现多了很多步骤.现在记录一下express中会话变量用法 安装express-session方法: 1.cnpm ...
- link-1-STL 标准模板库
STL(Standard Template Library,标准模版库)是C++语⾔言标准中的重要组成部分.STL以模板类和模版函数的形式为程序员提供了了各种数据结构和算法的实现,程序员吐过能够充分的 ...
- windows 查看端口占用(转)
开始--运行--cmd 进入命令提示符 输入netstat -ano 即可看到所有连接的PID 之后在任务管理器中找到这个PID所对应的程序如果任务管理器中没有PID这一项,可以在任务管理器中选&qu ...
- 微信小程序 笔记
1.Input 输入控件 <input type='digit' placeholder='0.00'></input> 如果要使用单纯的数字控件,使那么可以将type设置为d ...