【HNOI2016】最小公倍数

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

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

分块真是灵活啊!

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 100005
#define M 100005 using namespace std;
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;} int n,m,q;
struct edge {
int x,y,a,b;
bool operator <(const edge &e) const {return a<e.a;}
}e[M];
vector<edge>pre; int d[M];
int bel[M];
const int blk=350; bool cmp(const edge &A,const edge &B) {return A.b<B.b;} bool ans[N];
struct query {
int x,y,a,b;
int id;
query() {x=y=a=b=id=0;}
query(int X,int Y,int A,int B,int ID) {x=X,y=Y,a=A,b=B,id=ID;}
bool operator <(const query &a)const {return b<a.b;}
}; vector<query>Q[blk];
int f[N],mxa[N],mxb[N];
int dep[N];
int Getf(int v) {
while(f[v]!=v) v=f[v];
return v;
return v==f[v]?v:f[v]=Getf(f[v]);
} int lst[N];
void Init() {
for(int i=1;i<=n;i++) {
f[i]=i;
dep[i]=0;
mxa[i]=mxb[i]=0;
}
} struct ope {
int v,a,b,d;
ope() {v=a=b=d=0;}
ope(int V,int A,int B,int D) {v=V,a=A,b=B,d=D;}
}; vector<ope>ret;
void Get_back() {
while(ret.size()) {
int v=ret.back().v,a=ret.back().a,b=ret.back().b,d=ret.back().d;
f[v]=v,mxa[v]=a,mxb[v]=b;
dep[v]=d;
ret.pop_back();
}
} void Merge(int x,int y,int a,int b,int flag) {
x=Getf(x),y=Getf(y);
if(flag) {
ret.push_back(ope(x,mxa[x],mxb[x],dep[x]));
ret.push_back(ope(y,mxa[y],mxb[y],dep[y]));
}
if(x==y) {
mxa[x]=max(mxa[x],a);
mxb[x]=max(mxb[x],b);
return ;
}
if(dep[x]>dep[y]) swap(x,y);
f[x]=y;
if(dep[x]==dep[y]) dep[y]++;
mxa[y]=max(mxa[y],max(mxa[x],a));
mxb[y]=max(mxb[y],max(mxb[x],b));
} bool pd(int x,int y,int a,int b) {
if(Getf(x)!=Getf(y)) return 0;
x=Getf(x);
return mxa[x]>=lst[a]&&mxb[x]==b;
} void work(int k) {
Init();
sort(Q[k].begin(),Q[k].end());
sort(pre.begin(),pre.end(),cmp);
int tag=0;
int lx=(k-1)*blk+1,rx=min(m,k*blk); for(int i=0;i<Q[k].size();i++) {
int a=Q[k][i].a,b=Q[k][i].b;
while(tag<pre.size()&&pre[tag].b<=b) {
Merge(pre[tag].x,pre[tag].y,pre[tag].a,pre[tag].b,0);
tag++;
}
for(int j=lx;j<=a;j++) {
if(e[j].b<=Q[k][i].b) Merge(e[j].x,e[j].y,e[j].a,e[j].b,1);
}
ans[Q[k][i].id]=pd(Q[k][i].x,Q[k][i].y,a,b);
Get_back();
} for(int i=lx;i<=rx;i++) pre.push_back(e[i]);
} int main() {
n=Get(),m=Get();
for(int i=1;i<=m;i++) {
e[i].x=Get(),e[i].y=Get(),e[i].a=Get(),e[i].b=Get();
}
sort(e+1,e+1+m);
for(int i=1;i<=m;i++) d[i]=e[i].a;
for(int i=1;i<=m;i++) e[i].a=i;
for(int i=1;i<=m;i++) bel[i]=(i-1)/blk+1;
lst[1]=1;
for(int i=2;i<=m;i++)
if(d[i]==d[i-1]) lst[i]=lst[i-1];
else lst[i]=i;
q=Get();
int x,y,a,b;
for(int i=1;i<=q;i++) {
x=Get(),y=Get(),a=Get(),b=Get();
int p=upper_bound(d+1,d+1+m,a)-d-1;
if(p&&d[p]==a) Q[bel[p]].push_back(query(x,y,p,b,i));
} for(int i=1;i<=bel[m];i++) work(i);
for(int i=1;i<=q;i++)
(ans[i])?cout<<"Yes\n":cout<<"No\n";
return 0;
}

【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. [android] 开启新的activity获取他的返回值

    应用场景:打开一个新的activity,在这个activity上获取数据,返回给打开它的界面 短信发送时,可以直接选择系统联系人 界面布局是一个线性布局,里面右侧选择联系人在EditText的右上,因 ...

  2. P、NP、NPC、NP-Hard问题到底是何方神圣?

    最近在做一个求解有向图中回路的问题,老师说求解图中全部回路是一个NP难问题.突然想到P.NP.NPC.NP-hard的描述一致不是很清楚,所以又学习了一下. 在解释这四个概念之前,我们需要先知道两个问 ...

  3. 【Spring】31、Spring的EL表达式

    一.简介 Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大,简洁的装配Bean的方式,他可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中,更可以调用JD ...

  4. Docker 系列六(Docker Swarm 项目).

    一.前言 随着互联网快速发展,以及微服务架构的流行,服务器的压力越来越大.上一篇介绍的 Docker Compose 项目,可以将多个容器捏合在一起,实现容器间的通信,比如 Web 项目对 DB.Ca ...

  5. Java反射的简单入门

    1.Class的简单介绍 Class类的类表示正在运行的Java应用程序中的类和接口. 枚举是一种类,一个注解是一种接口, 每个数组也属于一个反映为类对象的类,该对象由具有相同元素类型和维数的所有数组 ...

  6. #WEB安全基础 : HTML/CSS | 0x3文件夹管理网站

    没有头脑的管理方式会酿成大灾难,应该使用文件夹管理网站 这是一个典型的管理方法,现在传授给你,听好了 下面是0x3初识a标签里使用的网站的目录,我把它重新配置了一下

  7. 谈谈 final finally finalize 区别

    声明 本篇所涉及的提问,正文的知识点,全都来自于杨晓峰的<Java核心技术36讲>,当然,我并不会全文照搬过来,毕竟这是付费的课程,应该会涉及到侵权之类的问题. 所以,本篇正文中的知识点, ...

  8. BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏(SG函数)

    Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 871  Solved: 365[Submit][Status][Discuss] Description ...

  9. (后端)解决code唯一码(java)简便方法

    public String next() { long appBootTimes = systemVariableService.getAppBootTimes(); return Long.toSt ...

  10. JavaScript中的原型链和继承

    理解原型链 在 JavaScript 的世界中,函数是一等公民. 上面这句话在很多地方都看到过.用我自己的话来理解就是:函数既当爹又当妈."当爹"是因为我们用函数去处理各种&quo ...