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> ...
随机推荐
- 在VMWare上安装ubuntu及VMWare&nbs…
在VMWare上安装ubuntu及VMWare Tools 一.摘要 该文主要介绍了如何在虚拟机上安装ubuntu,和安装VMWare Tools设置共享文件夹,最后对ubuntu做了简单的介绍. 二 ...
- Unity命令行打包
http://www.66acg.com/?post=137 补充 unity编辑器端获取打包命令行自定义参数,这个可以获取到所有打包时的参数 string[] runArgs = System.En ...
- spring eureka 启动过程
spring-eureka 在springCloud是类似于 zookeeper的存在,主要负责服务的注册发现. 1 由于是Servlet应用,所以Eureka需要通过servlet的相关监听器 ...
- 洛谷P1044 栈(Catalan数)
P1044 栈 题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). 栈的重要 ...
- 为产品接入微信支付解决方案(公司&个人)
微信支付个人及公司的区别 H5支付:主要实现的效果是在非微信内网页中点击支付,拉起微信APP内的微信支付进行付款. APP支付:主要实现的效果是在APP内部点击支付,拉起微信APP内的微信支付进行付款 ...
- Spark系列视频
大数据生态圈很大,很多开发者都仅仅接触到某个单一产品. Spark 是近年来比较流行的大数据计算框架,系统.平台要想用好Spark 这个产品,需要用到很多的产品. 本视频系列主要是为准备入坑大数据的童 ...
- [Java]HashSet的工作原理
概述 This class implements the Set interface, backed by a hash table (actually a HashMap instance). It ...
- Luogu P1155 双栈排序 图论?模拟吧。。
今天想做做图论,于是点开了这道题....(是二分图染色然而我没看出来) 四种操作及条件: 1. s1.push() 需满足 待push的元素小于栈顶 && { 若在原序列中,待push ...
- mongodb 分片技术
MongoDB Sharding Cluster 分片集群 规划:10个实例:38017-38026 (1)configserver:3台构成的复制集(1主两从,不支持arbiter)38018-38 ...
- ADC5513
一 C5513 u32 ADC5513_GetValue(void){ u32 ADValue,i; bool data_bit = false; C5513_SCK=0; C5513_CS ...