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> ...
随机推荐
- Eclipse中一个开发AspectJ的插件安…
eclipse4.2 EE版本插件安装 Eclipse最新版本Juno版本发布.部分插件版本跟不上. 选择自己需要的插件安装. eclipse http://www.eclipse.org/downl ...
- plsql 分页
select * from (select rownum rn,ps.* from (select * from user_t) ps ) where rn>=1 and rn<=10 ...
- linux 下jansson安装和使用
1.安装jansson ./configure make make install 2.生成帮助文档 cd doc make html 编译安装doc时提示 spinx-build not a com ...
- C++ Queues(队列)
C++ Queues(队列) C++队列是一种容器适配器,它给予程序员一种先进先出(FIFO)的数据结构.1.back() 返回一个引用,指向最后一个元素2.empty() 如果队列空则返回真3.fr ...
- hostent结构体和wsadata结构体
一.hostent结构体 使用这个东西,首先要包含2个头文件:#include <netdb.h>#include <sys/socket.h> struct hostent ...
- ACM-ICPC2018徐州网络赛 BE, GE or NE(对抗搜索+博弈+记忆化)
BE, GE or NE 23.58% 1000ms 262144K In a world where ordinary people cannot reach, a boy named &quo ...
- Android 自定义ViewGroup 实战篇 -> 实现FlowLayout
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38352503 ,本文出自[张鸿洋的博客] 1.概述 上一篇已经基本给大家介绍了如 ...
- python split 与join
1.string.join (saq):以string 为分隔符,将seq中所有的元素(字符串表示"")合并成一个新的字符串 2.string.split(str="&q ...
- Java8 中的 Optional
从 Java 8 引入的一个很有趣的特性是 Optional 类.Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException) —— 每个 Java 程序员都 ...
- react-native-syan-image-picker的使用
传送门 第一种方式:link 第一步:安装 1. npm install react-native-syan-image-picker --save 2. react-native link re ...