正题

题目链接:https://www.luogu.com.cn/problem/P3180


题目大意

\(n\)个点\(m\)条边的一个仙人掌,有点权。

\(Q\)次询问给出\(op,x,y\),封闭\(1\)到\(x\)号点的所有简单路径后\(x\)能到达的点的点权中,小于\(y\)且出现次数为奇数/偶数的权值数目。

\(1\leq n,Q\leq 10^5,1\leq m\leq 1.5\times 10^5,0\leq y,w_i\leq 10^6\)


解题思路

梦魇融合怪是吧

先对仙人掌建立一个圆方树,以\(1\)为根,那么能到达的就变为了子树的点权了。然后转换到\(dfs\)序的区间询问问题。

后面那个就和P4867-Gty的二逼妹子序列差不多了,考虑莫队,然后平衡结合的话用分块来维护区间和就好了。

时间复杂度\(O(n\sqrt y)\)


code

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<vector>
  5. #include<stack>
  6. #include<cmath>
  7. using namespace std;
  8. const int N=1e6+10,M=1100;
  9. struct node{
  10. int l,r,lim,k,id;
  11. }q[N];
  12. int n,m,Q,T,dfc,dfn[N],low[N],rfn[N],pos[N],c[N];
  13. int w[N],ans[N],L[M],R[M],v[2][N],sum[2][M];
  14. vector<int> G[N],H[N];stack<int> s;
  15. void tarjan(int x){
  16. dfn[x]=low[x]=++dfc;s.push(x);
  17. for(int i=0;i<G[x].size();i++){
  18. int y=G[x][i];
  19. if(!dfn[y]){
  20. tarjan(y);
  21. low[x]=min(low[x],low[y]);
  22. if(low[y]==dfn[x]){
  23. ++n;int k;
  24. do{
  25. k=s.top();s.pop();
  26. H[n].push_back(k);
  27. H[k].push_back(n);
  28. }while(k!=y);
  29. H[n].push_back(x);
  30. H[x].push_back(n);
  31. }
  32. }
  33. else low[x]=min(low[x],dfn[y]);
  34. }
  35. return;
  36. }
  37. void dfs(int x,int fa){
  38. dfn[++dfc]=x;rfn[x]=dfc;
  39. for(int i=0;i<H[x].size();i++){
  40. int y=H[x][i];
  41. if(y==fa)continue;
  42. dfs(y,x);
  43. }
  44. low[x]=dfc;
  45. }
  46. bool cmp(node x,node y){
  47. if(x.l/T==y.l/T)return x.r<y.r;
  48. return x.l<y.l;
  49. }
  50. void Add(int x,int f){
  51. if(c[x])v[c[x]&1][x]--,sum[c[x]&1][pos[x]]--;
  52. c[x]+=f;
  53. if(c[x])v[c[x]&1][x]++,sum[c[x]&1][pos[x]]++;
  54. return;
  55. }
  56. int Ask(int k,int l,int r){
  57. if(!r)return 0;
  58. int x=pos[l],y=pos[r],ans=0;
  59. if(x==y){
  60. for(int i=l;i<=r;i++)
  61. ans+=v[k][i];
  62. return ans;
  63. }
  64. for(int i=l;i<=R[x];i++)ans+=v[k][i];
  65. for(int i=L[y];i<=r;i++)ans+=v[k][i];
  66. for(int i=x+1;i<y;i++)ans+=sum[k][i];
  67. return ans;
  68. }
  69. int main()
  70. {
  71. scanf("%d%d",&n,&m);
  72. for(int i=1;i<=n;i++)
  73. scanf("%d",&w[i]);
  74. for(int i=1;i<=m;i++){
  75. int x,y;
  76. scanf("%d%d",&x,&y);
  77. G[x].push_back(y);
  78. G[y].push_back(x);
  79. }
  80. tarjan(1);dfc=0;
  81. dfs(1,1);T=sqrt(1e6);
  82. for(int i=1;i<=T;i++)L[i]=R[i-1]+1,R[i]=i*T;
  83. if(R[T]!=1e6)++T,L[T]=R[T-1]+1,R[T]=n;
  84. for(int i=1;i<=T;i++)
  85. for(int j=L[i];j<=R[i];j++)pos[j]=i;
  86. scanf("%d",&Q);
  87. for(int i=1;i<=Q;i++){
  88. int x;
  89. scanf("%d%d%d",&q[i].k,&x,&q[i].lim);
  90. q[i].l=rfn[x];q[i].r=low[x];q[i].id=i;
  91. }
  92. sort(q+1,q+1+Q,cmp);
  93. int l=1,r=0;
  94. for(int i=1;i<=Q;i++){
  95. while(l<q[i].l)Add(w[dfn[l]],-1),l++;
  96. while(l>q[i].l)l--,Add(w[dfn[l]],1);
  97. while(r<q[i].r)r++,Add(w[dfn[r]],1);
  98. while(r>q[i].r)Add(w[dfn[r]],-1),r--;
  99. ans[q[i].id]=Ask(q[i].k,1,q[i].lim);
  100. }
  101. for(int i=1;i<=Q;i++)
  102. printf("%d\n",ans[i]);
  103. return 0;
  104. }

P3180-[HAOI2016]地图【圆方树,莫队,分块】的更多相关文章

  1. 【CodeForces】700 D. Huffman Coding on Segment 哈夫曼树+莫队+分块

    [题目]D. Huffman Coding on Segment [题意]给定n个数字,m次询问区间[l,r]的数字的哈夫曼编码总长.1<=n,m,ai<=10^5. [算法]哈夫曼树+莫 ...

  2. luogu P3180 [HAOI2016]地图 仙人掌 线段树合并 圆方树

    LINK:地图 考虑如果是一棵树怎么做 权值可以离散 那么可以直接利用dsu on tree+树状数组解决. 当然 也可以使用莫队 不过前缀和比较难以维护 外面套个树状数组又带了个log 套分块然后就 ...

  3. [BZOJ3236][AHOI2013]作业:树套树/莫队+分块

    分析 第一问随便搞,直接说第二问. 令原数列为\(seq\),\(pre_i\)为\(seq_i\)这个值上一个出现的位置,于是可以简化询问条件为: \(l \leq i \leq r\) \(a \ ...

  4. P3180 [HAOI2016]地图

    P3180 [HAOI2016]地图 显然,这是一个仙人掌图 inline void tarjan(LL u,LL fa){ low[u]=dfn[u]=++tot, pre[tot]=u; for( ...

  5. BZOJ1023:[SHOI2008]cactus仙人掌图(圆方树,DP,单调队列)

    Description 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus). 所谓简单回路就是指在图上不重复经过任何一个顶点 ...

  6. BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)

    Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...

  7. 【BZOJ5329】【SDOI2018】战略游戏(圆方树,虚树)

    [BZOJ5329][SDOI2018]战略游戏(圆方树,虚树) 题面 BZOJ 洛谷 Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战 ...

  8. [JZOJ 5909] [NOIP2018模拟10.16] 跑商(paoshang) 解题报告 (圆方树)

    题目链接: https://jzoj.net/senior/#contest/show/2529/2 题目: 题目背景:尊者神高达很穷,所以他需要跑商来赚钱题目描述:基三的地图可以看做 n 个城市,m ...

  9. 圆方树简介(UOJ30:CF Round #278 Tourists)

    我写这篇博客的原因 证明我也是学过圆方树的 顺便存存代码 前置技能 双联通分量:点双 然后就没辣 圆方树 建立 新建一个图 定义原图中的所有点为圆点 对于每个点双联通分量(只有两个点的也算) 建立一个 ...

随机推荐

  1. java导出excel(easypoi)

    介绍 easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板 ...

  2. WPF中实现动画的几种效果(最基础方式)

    参考网址:https://blog.csdn.net/qq_45096273/article/details/106256397 在动画之前我们先了解一下几个声明式动画中常用的元素: 一.Storyb ...

  3. 【springcloud】API Gateway 的路由和过滤(Zuul--1)

    转自:https://blog.csdn.net/pengjunlee/article/details/87084646 Zuul是什么? API Gateway 是随着微服务(Microservic ...

  4. webapp网络定位

    1 <script> 2 var x=document.getElementById("demo"); 3 function getLocation() 4 { 5 i ...

  5. 从eclipse转idea不适记录【持续更新】

    使用eclipse和idea时,快捷键对比 从一些最扎心的开始: 关于print一类的打印输出:System.out.println()补全 idea中可以sout.souf.serr:分别对应out ...

  6. 老鼠走迷宫I

    转自:http://blog.csdn.net/holymaple/article/details/8582517 说明:老鼠走迷宫是递回求解的基本提醒,我们在二维阵列中使用2来表示迷宫墙壁,使用1来 ...

  7. 国内Git官网下载windows版本慢的问题,推荐一个国内镜像

    话不多说了,给你们镜像地址: https://npm.taobao.org/mirrors/git-for-windows/ 不用谢.点右边打赏个一毛钱,告诉我你来过        !_!

  8. ubuntu下安装teamiewer

    下载地址: https://download.teamviewer.com/download/linux/teamviewer_amd64.deb 如果无法下载,则在https://www.teamv ...

  9. Ubuntu16.04 Linux 下无痛安装、配置Gogs

    本文在Win7+VMware的ubuntu 16.04中测试,安装Gogs,Install from binary. 准备工作: sudo apt-get install git sudo addus ...

  10. MySQL alter table时执行innobackupex全备再看Seconds_Behind_Master

    1.场景描述 早上7:25 接到Report中心同学告警,昨天业务报表数据没有完整跑出来,缺少500位业务员的数据,并且很快定位到,缺少的是huabei_order库上的数据.Report中心的数据是 ...