【HNOI2016】最小公倍数

容易想到先将所有边按\(a\)排序,然后处理\(b\)。(然后我就不会了

我们按\(a\)的权值分块,处理\(a\)权值位于第\(k\)个块的询问的时候,我们先将询问按\(B\)排序,然后将\([1,k-1]\)块中所有\(b_i\leq B\)的边加入并查集中。然后在第\(k\)个块中还有一些边没有加入,我们就暴力加,然后再暴力回退就好了。

分块真是灵活啊!

代码:

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define N 100005
  4. #define M 100005
  5. using namespace std;
  6. inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
  7. int n,m,q;
  8. struct edge {
  9. int x,y,a,b;
  10. bool operator <(const edge &e) const {return a<e.a;}
  11. }e[M];
  12. vector<edge>pre;
  13. int d[M];
  14. int bel[M];
  15. const int blk=350;
  16. bool cmp(const edge &A,const edge &B) {return A.b<B.b;}
  17. bool ans[N];
  18. struct query {
  19. int x,y,a,b;
  20. int id;
  21. query() {x=y=a=b=id=0;}
  22. query(int X,int Y,int A,int B,int ID) {x=X,y=Y,a=A,b=B,id=ID;}
  23. bool operator <(const query &a)const {return b<a.b;}
  24. };
  25. vector<query>Q[blk];
  26. int f[N],mxa[N],mxb[N];
  27. int dep[N];
  28. int Getf(int v) {
  29. while(f[v]!=v) v=f[v];
  30. return v;
  31. return v==f[v]?v:f[v]=Getf(f[v]);
  32. }
  33. int lst[N];
  34. void Init() {
  35. for(int i=1;i<=n;i++) {
  36. f[i]=i;
  37. dep[i]=0;
  38. mxa[i]=mxb[i]=0;
  39. }
  40. }
  41. struct ope {
  42. int v,a,b,d;
  43. ope() {v=a=b=d=0;}
  44. ope(int V,int A,int B,int D) {v=V,a=A,b=B,d=D;}
  45. };
  46. vector<ope>ret;
  47. void Get_back() {
  48. while(ret.size()) {
  49. int v=ret.back().v,a=ret.back().a,b=ret.back().b,d=ret.back().d;
  50. f[v]=v,mxa[v]=a,mxb[v]=b;
  51. dep[v]=d;
  52. ret.pop_back();
  53. }
  54. }
  55. void Merge(int x,int y,int a,int b,int flag) {
  56. x=Getf(x),y=Getf(y);
  57. if(flag) {
  58. ret.push_back(ope(x,mxa[x],mxb[x],dep[x]));
  59. ret.push_back(ope(y,mxa[y],mxb[y],dep[y]));
  60. }
  61. if(x==y) {
  62. mxa[x]=max(mxa[x],a);
  63. mxb[x]=max(mxb[x],b);
  64. return ;
  65. }
  66. if(dep[x]>dep[y]) swap(x,y);
  67. f[x]=y;
  68. if(dep[x]==dep[y]) dep[y]++;
  69. mxa[y]=max(mxa[y],max(mxa[x],a));
  70. mxb[y]=max(mxb[y],max(mxb[x],b));
  71. }
  72. bool pd(int x,int y,int a,int b) {
  73. if(Getf(x)!=Getf(y)) return 0;
  74. x=Getf(x);
  75. return mxa[x]>=lst[a]&&mxb[x]==b;
  76. }
  77. void work(int k) {
  78. Init();
  79. sort(Q[k].begin(),Q[k].end());
  80. sort(pre.begin(),pre.end(),cmp);
  81. int tag=0;
  82. int lx=(k-1)*blk+1,rx=min(m,k*blk);
  83. for(int i=0;i<Q[k].size();i++) {
  84. int a=Q[k][i].a,b=Q[k][i].b;
  85. while(tag<pre.size()&&pre[tag].b<=b) {
  86. Merge(pre[tag].x,pre[tag].y,pre[tag].a,pre[tag].b,0);
  87. tag++;
  88. }
  89. for(int j=lx;j<=a;j++) {
  90. if(e[j].b<=Q[k][i].b) Merge(e[j].x,e[j].y,e[j].a,e[j].b,1);
  91. }
  92. ans[Q[k][i].id]=pd(Q[k][i].x,Q[k][i].y,a,b);
  93. Get_back();
  94. }
  95. for(int i=lx;i<=rx;i++) pre.push_back(e[i]);
  96. }
  97. int main() {
  98. n=Get(),m=Get();
  99. for(int i=1;i<=m;i++) {
  100. e[i].x=Get(),e[i].y=Get(),e[i].a=Get(),e[i].b=Get();
  101. }
  102. sort(e+1,e+1+m);
  103. for(int i=1;i<=m;i++) d[i]=e[i].a;
  104. for(int i=1;i<=m;i++) e[i].a=i;
  105. for(int i=1;i<=m;i++) bel[i]=(i-1)/blk+1;
  106. lst[1]=1;
  107. for(int i=2;i<=m;i++)
  108. if(d[i]==d[i-1]) lst[i]=lst[i-1];
  109. else lst[i]=i;
  110. q=Get();
  111. int x,y,a,b;
  112. for(int i=1;i<=q;i++) {
  113. x=Get(),y=Get(),a=Get(),b=Get();
  114. int p=upper_bound(d+1,d+1+m,a)-d-1;
  115. if(p&&d[p]==a) Q[bel[p]].push_back(query(x,y,p,b,i));
  116. }
  117. for(int i=1;i<=bel[m];i++) work(i);
  118. for(int i=1;i<=q;i++)
  119. (ans[i])?cout<<"Yes\n":cout<<"No\n";
  120. return 0;
  121. }

【HNOI2016】最小公倍数的更多相关文章

  1. BZOJ 4537: [Hnoi2016]最小公倍数 [偏序关系 分块]

    4537: [Hnoi2016]最小公倍数 题意:一张边权无向图,多组询问u和v之间有没有一条a最大为a',b最大为b'的路径(不一定是简单路径) 首先想到暴力做法,题目要求就是判断u和v连通,并查集 ...

  2. 【LG3247】[HNOI2016]最小公倍数

    [LG3247][HNOI2016]最小公倍数 题面 洛谷 题解 50pts 因为拼凑起来的部分分比较多,所以就放一起了. 以下设询问的\(a,b\)为\(A,B\), 复杂度\(O(nm)\)的:将 ...

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

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

  4. [BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集

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

  5. 【BZOJ4537】[Hnoi2016]最小公倍数 分块

    [BZOJ4537][Hnoi2016]最小公倍数 Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在 ...

  6. 4537: [Hnoi2016]最小公倍数

    Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你 ...

  7. bzoj 4537 HNOI2016 最小公倍数

    Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,-,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你 ...

  8. [HNOI2016]最小公倍数

    题目描述 给定一张N个顶点M条边的无向图(顶点编号为1,2,...,n),每条边上带有权值.所有权值都可以分解成2a∗3b2^a*3^b2a∗3b 的形式. 现在有q个询问,每次询问给定四个参数u.v ...

  9. 洛谷P3247 [HNOI2016]最小公倍数 [分块,并查集]

    洛谷 思路 显然,为了达到这个最小公倍数,只能走\(a,b\)不是很大的边. 即,当前询问的是\(A,B\),那么我们只能走\(a\leq A,b\leq B\)的边. 然而,为了达到这最小公倍数,又 ...

  10. [HNOI2016]最小公倍数 (可回退并查集,回滚莫队)

    题面 题目链接 题目描述 给定一张 N N N 个顶点 M M M 条边的无向图(顶点编号为 1 , 2 , - , n 1,2,\ldots,n 1,2,-,n),每条边上带有权值.所有权值都可以分 ...

随机推荐

  1. 重构——一个小例子

    菜鸟区域,老鸟绕路! 原代码,这是一个可以借阅影片的小程序,你可以想象成某个大型系统,我想代码应该都能很容易看懂: using System; using System.Collections.Gen ...

  2. JQuery官方学习资料(译):选择器的运作

    Getters 和 Setters     JQuery的方法重载,方法设置和获取值一般使用相同名称的方法,当一个方法用来设置一个值的时候称之为Setter,当一个方法用来获取一个值的时候称之为Get ...

  3. [android] 线性布局和布局的组合

    /****************2016年4月25日 更新******************************/ 知乎:对于开发者来说,Android 的开发者选项里有哪些实用的功能? 汤涛 ...

  4. 表单时间和定时器this的指向

    1.针对表单的 form 表单  input 输入框 select 下拉列表  textarea 文本域 type 类型 radio 单选框 checkbox 多选框 password 密码框 but ...

  5. Fundebug能够捕获这些BUG

    摘要:Fundebug的JavaScript监控插件更新至0.1.0,可以监控3种不同类型的前端BUG:JavaScript执行错误.资源加载错误.HTTP请求错误. 从简单的onerror开始,Fu ...

  6. canvas 画时钟 会动呦

    //半径 var r = 130; //重置原点 ctx.save(); ctx.translate(400, 500); //使用translate重置原点 function drawClock() ...

  7. struts2框架-----Action

    控制器Action Action对象是struts2框架的核心,每个URL映射到特定的Action,其提供处理来自用户的请求所需要的处理逻辑.Action有两个重要的功能,即将数据从请求传递到视图和协 ...

  8. C#自定义控件、用户控件、动态加载菜单按钮

    一.效果图,动态加载5个菜单按钮: 二.实现方法 1.创建用户控件 2.在用户控件拖入toolStrip 3.进入用户控件的Lood事件,这里自动添加5个选  ToolStripMenuItem,后期 ...

  9. nodejs+expressjs+ws实现了websocket即时通讯,服务器和客户端互相通信

    nodejs代码 // 导入WebSocket模块: const WebSocket = require('ws'); // 引用Server类: const WebSocketServer = We ...

  10. es6 语法 (Generator)

    { // 长轮询 let ajax=function* (){ yield new Promise(function(resolve,reject){ setTimeout(function () { ...