【输入格式】
第一行一个正整数 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+转化)相关推荐

  1. 【HDU - 5452】Minimum Cut(树形dp 或 最近公共祖先lca+树上差分,转化tricks,思维)

    题干: Given a simple unweighted graph GG (an undirected graph containing no loops nor multiple edges) ...

  2. HDU 5266 pog loves szh III(在线倍增LCA+ST)

    Description 给出一棵有n个节点的树,定义1为树根,有q次询问,每次询问区间[a,b]中所有节点的LCA Input 第一行为一整数n表示节点数,之后n-1行每行两个整数a和b表示树的一条边 ...

  3. HDU 5266 pog loves szh III【LCA RMQ】

    B - pog loves szh III 题目:添加链接描述 题意:找出区域l到r的LCA->找l和r的LCA 分析: 链式前向星存树,先用dfs处理结点倍增关系. 然后从循环处理较深结点,直 ...

  4. 【hdu5266】pog loves szh III (LCA+线段树)

    题意:给一颗树,Q次询问L,L+1,L+2...R的LCA 题目传送门 以LCA为权建线段树,直接查询即可 (我用树剖找LCA) 代码: #include<iostream> #inclu ...

  5. hdu 5266 pog loves szh III LCA+RMQ

    题意: 给你一棵树,然后询问l~r节点的最近公共祖先(LCA). 思路: 用RMQ维护一段区间的LCA,然后询问时,将两个区间的LCA再求一次LCA即可. code: #pragma comment( ...

  6. The Shortest Statement CodeForces - 1051F LCA+最短路

    太弱了... 一开始看到题感觉是跑一个最小生成树在上边进行LCA就行了,但是发现过不了样例,然后就是就想到了之前做过类似做法的题目,就是非生成树上的边最多只有21条,然后就那些边记录下来,通过每一条边 ...

  7. POJ - 1986 Distance Queries 倍增求LCA

    题意还是很有病的,说了半天后边的方向都没用的,意思就是跟样例一样求两点间的距离,裸的LCA 两个点x,y的距离=dis[x]+dis[y]-2*dis[LCA(x,y)]; 三个点x,y,z的距离=d ...

  8. 【BZOJ-3712】Fiolki LCA + 倍增 (idea题)

    3712: [PA2014]Fiolki Time Limit: 30 Sec  Memory Limit: 128 MB Submit: 303  Solved: 67 [Submit][Statu ...

  9. LCA ---- E. Tree Queries[LCA或者dfs序的解法]

    题目链接 题目大意:就是给你一颗树,然后qqq次询问每次询问会给出kkk个点,要求你判断一下这些点是否在存在一条从1到某个点u的链使得这k个点都在这条链上或者距离这条链距离为1的位置上 解法1:dfs ...

  10. 主席树 ---- LCA(树上第k大)Count on a tree

    题目链接:https://www.spoj.com/problems/COT/en/ 题意: 给你一颗树,问你u,v结点这条路径上第k大是多少. 思路:就是说先将无根树转化为有根树,然后对每一条链建立 ...

最新文章

  1. pythonexcel介绍_Python 中pandas.read_excel详细介绍
  2. Redis 5.0.3默认配置启动报错解决方法
  3. ITK:图像阈值演示可用的阈值算法
  4. 上几个WebAPI就算微服务架构?Too Young!
  5. 使用sqlite3创建数据库表的时候须要注意
  6. Android TextView通过SpannableString设置字体、大小、颜色、样式、超级链接
  7. SQL:union \union all、intersect 、except的用法
  8. 前端调试debugf_前端应该掌握的这些Debug技巧,能够快速提升你的前端开发能力...
  9. MySQL数据库regdate_第十五章 MySQL 数据库
  10. 【谷粒学院】项目总结
  11. Linux系统连接以太网与WIFI的方法
  12. java opencv 模板匹配算法_OpenCV模板匹配算法详解
  13. 关于微信8.0.0以下版本登录版本验证的解决办法
  14. 欧姆字符的编码c语言,如何在word中打出欧姆符号呢?
  15. 自动化生产线仿真教学
  16. 阿里云操作系统——飞天(Apsaras)
  17. iOS常用第三方库大全
  18. 简单说下antv图表的使用
  19. java 学习7.13 正则表达式 Pattern和Matcher类 Math类 Random类 System类 BigDecimal类 Date类 SimpleDateFormat类 Cale
  20. [学习笔记-扫盲]KL15,KL30

热门文章

  1. Pr 音频效果参考:调制
  2. 分享盘点9个可免费使用的网站CDN加速服务
  3. thinkphp mysql order_ThinkPHP中order()的使用方法
  4. 如何用计算机串口烧录芯片,如何使用串口烧写xmc1301芯片.pdf
  5. TrendForce:2018年上半年电视面板出货年增11%
  6. 学会这5种排版方式,设计能力分分钟就能提高
  7. Word中插入MATLAB矢量图
  8. raid数据恢复案例之:服务器Raid5磁盘阵列数据恢复过程
  9. C# 读取xls格式的文件
  10. java中求梯形的面积_java 求梯形面积