ZYF loves set (lca+转化)
【输入格式】
第一行一个正整数 n。
接下来 n行描述集合 A1,A2,...,An。第一个数表示集合中元素的个数,之后给出集合中的元素。
接下来一行包含一个正整数 q。
接下来 q行每行描述一个询问,格式与之前相同。
【输出格式】
对于每组询问,输出一个整数表示答案。
【样例输入】
7
0
1 1
1 1
1 2
2 2 3
0
2 2 6
3
2 2 3
2 3 5
2 4 5
【样例输出】
3
3
4
【数据规模及约定】
对于 20%的数据,n,q<=50
对于 40%的数据,n,q<=1000
对于 100%的数据,n,q<=200000
输入文件大小不超过 15MB。
题解:题目中集合与集合的关系可以抽象成树的结构。
定义一个新集合就相当于是在一堆点的lca上在加入一个新节点
查询就是求一些点到根的路径上一共覆盖了多少点,可以利用dfs序以及点与点之间lca的深度关系来计算。
按dfs序排序,这样每个点都与与他距离最近的点相连,计算对答案的贡献的时候只需要+deep[now]-deep[lca(now,now-1)] 即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 10000003
#define M 500000
using namespace std;
int a[N],b[N],f[20][M],mi[20];
int point[M],next[M],v[M],pos[M],w[M],tot,cnt,size;
int n,m,t,l[N],deep[N],q[M],cur[M],st[M];
void add(int x,int y,int k)
{tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; w[tot]=k;//cout<<x<<" "<<y<<" "<<k<<endl;
}
void change(int x,int y)
{deep[y]=deep[x]+1;f[0][y]=x;for (int i=1;i<=18;i++){if (deep[y]-mi[i]<0) break;f[i][y]=f[i-1][f[i-1][y]];}
}
int lca(int x,int y)
{if (deep[x]<deep[y]) swap(x,y);int k=deep[x]-deep[y];for (int i=0;i<=18;i++)if ((k>>i)&1)x=f[i][x];if (x==y) return y;for (int i=18;i>=0;i--)if (f[i][x]!=f[i][y]){x=f[i][x];y=f[i][y];}return f[0][x];
}
void dfs(int x)
{q[x]=++size;for (int i=point[x];i;i=next[i])dfs(v[i]);
}
void dfs1()
{int top=0;for (int i=0;i<=n;i++) cur[i]=point[i];st[++top]=0;while(top){int x=st[top];if (!cur[x]){--top;q[x]=++size;continue;}int vt=v[cur[x]];st[++top]=vt; cur[x]=next[cur[x]];}
}
int cmp(int x,int y)
{return q[x]<q[y];
}
int main()
{freopen("set.in","r",stdin);freopen("set.out","w",stdout);scanf("%d",&n);mi[0]=1;for (int i=1;i<=19;i++) mi[i]=mi[i-1]*2;for (int i=1;i<=n;i++){int x; scanf("%d",&x); l[i]=l[i-1]+x;for (int j=l[i-1]+1;j<=l[i];j++)scanf("%d",&a[j]);}for (int i=1;i<=n;i++){if (l[i-1]-l[i]==0){pos[i]=++cnt;add(0,cnt,i);change(0,cnt);continue;}if (l[i]-l[i-1]==1){pos[i]=++cnt;add(pos[a[l[i]]],cnt,i);change(pos[a[l[i]]],cnt);continue;}int t=lca(pos[a[l[i-1]+1]],pos[a[l[i-1]+2]]);for (int j=l[i-1]+3;j<=l[i];j++)t=lca(pos[a[j]],t);pos[i]=++cnt;add(t,cnt,i);change(t,cnt);}//dfs(0);dfs1();//for (int i=1;i<=n;i++)//cout<<q[i]<<" ";//cout<<endl;scanf("%d",&m);for (int i=1;i<=m;i++){int x; scanf("%d",&x);for (int j=1;j<=x;j++)scanf("%d",&b[j]);sort(b+1,b+x+1,cmp);//for (int j=1;j<=x;j++)// cout<<b[j]<<" ";//cout<<endl;int ans=0;ans+=deep[b[1]];for (int j=2;j<=x;j++)ans+=deep[b[j]]-deep[lca(b[j],b[j-1])];printf("%d\n",ans);}
}
ZYF loves set (lca+转化)相关推荐
- 【HDU - 5452】Minimum Cut(树形dp 或 最近公共祖先lca+树上差分,转化tricks,思维)
题干: Given a simple unweighted graph GG (an undirected graph containing no loops nor multiple edges) ...
- HDU 5266 pog loves szh III(在线倍增LCA+ST)
Description 给出一棵有n个节点的树,定义1为树根,有q次询问,每次询问区间[a,b]中所有节点的LCA Input 第一行为一整数n表示节点数,之后n-1行每行两个整数a和b表示树的一条边 ...
- HDU 5266 pog loves szh III【LCA RMQ】
B - pog loves szh III 题目:添加链接描述 题意:找出区域l到r的LCA->找l和r的LCA 分析: 链式前向星存树,先用dfs处理结点倍增关系. 然后从循环处理较深结点,直 ...
- 【hdu5266】pog loves szh III (LCA+线段树)
题意:给一颗树,Q次询问L,L+1,L+2...R的LCA 题目传送门 以LCA为权建线段树,直接查询即可 (我用树剖找LCA) 代码: #include<iostream> #inclu ...
- hdu 5266 pog loves szh III LCA+RMQ
题意: 给你一棵树,然后询问l~r节点的最近公共祖先(LCA). 思路: 用RMQ维护一段区间的LCA,然后询问时,将两个区间的LCA再求一次LCA即可. code: #pragma comment( ...
- The Shortest Statement CodeForces - 1051F LCA+最短路
太弱了... 一开始看到题感觉是跑一个最小生成树在上边进行LCA就行了,但是发现过不了样例,然后就是就想到了之前做过类似做法的题目,就是非生成树上的边最多只有21条,然后就那些边记录下来,通过每一条边 ...
- POJ - 1986 Distance Queries 倍增求LCA
题意还是很有病的,说了半天后边的方向都没用的,意思就是跟样例一样求两点间的距离,裸的LCA 两个点x,y的距离=dis[x]+dis[y]-2*dis[LCA(x,y)]; 三个点x,y,z的距离=d ...
- 【BZOJ-3712】Fiolki LCA + 倍增 (idea题)
3712: [PA2014]Fiolki Time Limit: 30 Sec Memory Limit: 128 MB Submit: 303 Solved: 67 [Submit][Statu ...
- LCA ---- E. Tree Queries[LCA或者dfs序的解法]
题目链接 题目大意:就是给你一颗树,然后qqq次询问每次询问会给出kkk个点,要求你判断一下这些点是否在存在一条从1到某个点u的链使得这k个点都在这条链上或者距离这条链距离为1的位置上 解法1:dfs ...
- 主席树 ---- LCA(树上第k大)Count on a tree
题目链接:https://www.spoj.com/problems/COT/en/ 题意: 给你一颗树,问你u,v结点这条路径上第k大是多少. 思路:就是说先将无根树转化为有根树,然后对每一条链建立 ...
最新文章
- pythonexcel介绍_Python 中pandas.read_excel详细介绍
- Redis 5.0.3默认配置启动报错解决方法
- ITK:图像阈值演示可用的阈值算法
- 上几个WebAPI就算微服务架构?Too Young!
- 使用sqlite3创建数据库表的时候须要注意
- Android TextView通过SpannableString设置字体、大小、颜色、样式、超级链接
- SQL:union \union all、intersect 、except的用法
- 前端调试debugf_前端应该掌握的这些Debug技巧,能够快速提升你的前端开发能力...
- MySQL数据库regdate_第十五章 MySQL 数据库
- 【谷粒学院】项目总结
- Linux系统连接以太网与WIFI的方法
- java opencv 模板匹配算法_OpenCV模板匹配算法详解
- 关于微信8.0.0以下版本登录版本验证的解决办法
- 欧姆字符的编码c语言,如何在word中打出欧姆符号呢?
- 自动化生产线仿真教学
- 阿里云操作系统——飞天(Apsaras)
- iOS常用第三方库大全
- 简单说下antv图表的使用
- java 学习7.13 正则表达式 Pattern和Matcher类 Math类 Random类 System类 BigDecimal类 Date类 SimpleDateFormat类 Cale
- [学习笔记-扫盲]KL15,KL30