4537: [Hnoi2016]最小公倍数

Time Limit: 40 Sec  Memory Limit: 512 MB
Submit: 1474  Solved: 521
[Submit][Status][Discuss]

Description

  给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值。所有权值都可以分解成2^a*3^b
的形式。现在有q个询问,每次询问给定四个参数u、v、a和b,请你求出是否存在一条顶点u到v之间的路径,使得
路径依次经过的边上的权值的最小公倍数为2^a*3^b。注意:路径可以不是简单路径。下面是一些可能有用的定义
:最小公倍数:K个数a1,a2,…,ak的最小公倍数是能被每个ai整除的最小正整数。路径:路径P:P1,P2,…,Pk是顶
点序列,满足对于任意1<=i<k,节点Pi和Pi+1之间都有边相连。简单路径:如果路径P:P1,P2,…,Pk中,对于任意1
<=s≠t<=k都有Ps≠Pt,那么称路径为简单路径。

Input

  输入文件的第一行包含两个整数N和M,分别代表图的顶点数和边数。接下来M行,每行包含四个整数u、v、a、
b代表一条顶点u和v之间、权值为2^a*3^b的边。接下来一行包含一个整数q,代表询问数。接下来q行,每行包含四
个整数u、v、a和b,代表一次询问。询问内容请参见问题描述。1<=n,q<=50000、1<=m<=100000、0<=a,b<=10^9

Output

  对于每次询问,如果存在满足条件的路径,则输出一行Yes,否则输出一行 No(注意:第一个字母大写,其余
字母小写) 。

Sample Input

4 5
1 2 1 3
1 3 1 2
1 4 2 1
2 4 3 2
3 4 2 2
5
1 4 3 3
4 2 2 3
1 3 2 2
2 3 2 2
1 3 4 4

Sample Output

Yes
Yes
Yes
No
No

HINT

 

Source

考虑暴力做法,对于每一个询问,暴力加入满足询问的边,然后维护联通性和maxp,maxqmaxp,maxq,如果满足条件则YesYes。 
两个条件的限制似乎很难用别的数据结构优化掉,那么考虑分块,先以pp为第一关键字,qq为第二关键字排序,每$m^{0.5}$分成一块。然后把每一个询问归类到相应的块中,使得这个询问的$p$大于等于块的$p$最小值小于等于最大值。 
依次扫每个块,把每个块的询问取出来。设当前的块号是$i$,那么我们把$1$到$i-1$的块里面的所有的边按$b$排序,

再把这个块内的询问按$q$排序。然后扫$1$到$i-1$的符合当前询问的边,加入并查集。对于i块内的边,只能暴力扫然后加入并查集了,注意处理完这个询问后,要撤销掉在该块内加入的边。

所以此题的并查集不能路径压缩,要用启发式合并或按秩合并,两者都是$logn$的,总的时间复杂度时$O(n^{1.5}logn)$。

将代码中的启发式换成按秩合并可AC否则TLE

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cstdio>
  5. #include<cmath>
  6. #include<algorithm>
  7. #define ll long long
  8. #define maxn 140105
  9. using namespace std;
  10. int read() {
  11. int x=,f=;char ch=getchar();
  12. for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
  13. for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
  14. return x*f;
  15. }
  16. int n,m,k;
  17. struct data {
  18. int a,b,p,q,id,f;
  19. bool operator <(const data tmp) const{
  20. return p==tmp.p?q<tmp.q:p<tmp.p;
  21. }
  22. }e[maxn],ask[maxn],tmp[maxn],sta[maxn];
  23. int fa[maxn],sz,ma[maxn],mb[maxn],size[maxn];
  24. int ans[maxn];
  25. int find(int x) {return fa[x]==x?fa[x]:find(fa[x]);}
  26. int cnt=;
  27. void merge(int x,int y,int a,int b) {
  28. x=find(x),y=find(y);
  29. if(size[x]>size[y]) swap(x,y);
  30. sta[++cnt].a=x;sta[cnt].b=y;sta[cnt].p=ma[y];sta[cnt].q=mb[y];sta[cnt].f=fa[x];sta[cnt].id=size[y];
  31. if(x==y) {
  32. ma[x]=max(ma[x],a);
  33. mb[x]=max(mb[x],b);
  34. }
  35. else {
  36. fa[x]=y;
  37. size[y]+=size[x];
  38. ma[y]=max(ma[y],a);
  39. mb[y]=max(mb[y],b);
  40. ma[y]=max(ma[x],ma[y]);
  41. mb[y]=max(mb[x],mb[y]);
  42. }
  43. }
  44. bool cmp(data a,data b) {return a.q==b.q?a.p<b.p:a.q<b.q;}
  45. int main() {
  46.  
  47. n=read(),m=read();
  48. for(int i=;i<=m;i++) {
  49. e[i].a=read();e[i].b=read();e[i].p=read();e[i].q=read();
  50. }
  51. sort(e+,e+m+);
  52. sz=sqrt(m);
  53. k=read();
  54. for(int i=;i<=k;i++) {
  55. ask[i].a=read(),ask[i].b=read(),ask[i].p=read(),ask[i].q=read();ask[i].id=i;
  56. }
  57. sort(ask+,ask+k+,cmp);
  58. for(int i=;i<=m;i+=sz) {
  59. int top=;
  60. for(int j=;j<=k;j++) if(ask[j].p>=e[i].p&&(i+sz>m||ask[j].p<e[i+sz].p)) tmp[++top]=ask[j];
  61. sort(e+,e+i,cmp);
  62. for(int j=;j<=n;j++) fa[j]=j,size[j]=,ma[j]=mb[j]=-;
  63. int w=;
  64. for(int j=;j<=top;j++) {
  65. for(;w<i;w++) {
  66. if(e[w].q>tmp[j].q) break;
  67. merge(e[w].a,e[w].b,e[w].p,e[w].q);
  68. }
  69. cnt=;
  70. for(int t=i;t<i+sz;t++) {
  71. if(e[t].p<=tmp[j].p&&e[t].q<=tmp[j].q) merge(e[t].a,e[t].b,e[t].p,e[t].q);
  72. }
  73. int t1=find(tmp[j].a),t2=find(tmp[j].b);
  74. if(t1==t2&&ma[t1]==tmp[j].p&&mb[t1]==tmp[j].q) ans[tmp[j].id]=;
  75. while(cnt) {
  76. fa[sta[cnt].a]=sta[cnt].f;
  77. ma[sta[cnt].b]=sta[cnt].p;
  78. mb[sta[cnt].b]=sta[cnt].q;
  79. size[sta[cnt].b]=sta[cnt].id;
  80. cnt--;
  81. }
  82. }
  83. }
  84. for(int i=;i<=k;i++) if(ans[i]) puts("Yes");else puts("No");
  85.  
  86. }

[BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集的更多相关文章

  1. [BZOJ4537][HNOI2016]最小公倍数(分块+并查集)

    4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1687  Solved: 607[Submit][Stat ...

  2. BZOJ4537 HNOI2016最小公倍数(莫队+并查集)

    考虑边只有一种权值的简化情况.那么当且仅当两点可以通过边权<=x的边连通,且连通块内最大边权为x时,两点间存在路径max为x的路径.可以发现两种权值是类似的,当且仅当两点可以通过边权1<= ...

  3. 【bzoj2049】[Sdoi2008]Cave 洞穴勘测——线段树上bfs求可撤销并查集

    题面 2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 12030 Solved: 6024 Desc ...

  4. bzoj2049 线段树 + 可撤销并查集

    https://www.lydsy.com/JudgeOnline/problem.php?id=2049 线段树真神奇 题意:给出一波操作,拆边加边以及询问两点是否联通. 听说常规方法是在线LCT, ...

  5. CodeForces892E 可撤销并查集/最小生成树

    http://codeforces.com/problemset/problem/892/E 题意:给出一个 n 个点 m 条边的无向图,每条边有边权,共 Q 次询问,每次给出 ki​ 条边,问这些边 ...

  6. BZOJ4358: permu(带撤销并查集 不删除莫队)

    题意 题目链接 Sol 感觉自己已经老的爬不动了.. 想了一会儿,大概用个不删除莫队+带撤销并查集就能搞了吧,\(n \sqrt{n} logn\)应该卡的过去 不过不删除莫队咋写来着?....跑去学 ...

  7. 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic

    本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...

  8. codeforces 892E(离散化+可撤销并查集)

    题意 给出一个n个点m条边的无向联通图(n,m<=5e5),有q(q<=5e5)个询问 每个询问询问一个边集{Ei},回答这些边能否在同一个最小生成树中 分析 要知道一个性质,就是权值不同 ...

  9. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

随机推荐

  1. 【SSH】——Hibernate三种状态之间的转化

    Hibernate的三种状态为:transient.persistent和detached.对这三种状态的理解可以结合Session缓存,在Session缓存中的状态为persistent,另外两种不 ...

  2. Java使用泛型的困顿

    原文有点儿胡说的意味,删了,有空再次更新这篇博文~

  3. RxJS & Angular

    RxJS & Angular https://www.learnrxjs.io/ https://rxjs-cn.github.io/learn-rxjs-operators/ https:/ ...

  4. Currying & 柯里化

    Currying & 柯里化 函数式编程 https://www.cnblogs.com/xgqfrms/p/5730527.html https://en.wikipedia.org/wik ...

  5. Bootstrap中的Affix插件

    我们为什么要用bootstrap?因为懒!哦....不,是因为方便,呃...意思差不多. 今天来说说Affix这个插件,它可以使导航栏固定,免去了自己手写的麻烦,用着非常方便,废话不多说,下面是用法. ...

  6. elasticsearch集群及filebeat server和logstash server

    elasticsearch集群及filebeat server和logstash server author:JevonWei版权声明:原创作品blog:http://119.23.52.191/ 实 ...

  7. 【题解】[国家集训队]Crash的数字表格 / JZPTAB

    求解\(\sum_{i = 1}^{n}\sum_{j = 1}^{m}lcm\left ( i,j \right )\). 有\(lcm\left ( i,j \right )=\frac{ij}{ ...

  8. AtCoder Grand Contest 028 B - Removing Blocks 解题报告

    B - Removing Blocks Time limit : 2sec / Memory limit : 1024MB Score : 600 points ## Problem Statemen ...

  9. 【BZOI 1202 狡猾的商人】

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4149  Solved: 1994[Submit][Status][Discuss] Descript ...

  10. 在linux环境下让java代码生效的步骤

    1.kill jboss 2.compile 3.deploy 4.bootstrap jboss.