2017.7.22 hnoi2016 最小公倍数

#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 50010
#define M 100010
#define RG register
#define inf 0x3f3f3f3f
using namespace std;
bool ans[N];
struct stac{
    int u,v,op;
}sta[40000];
struct node{
    int a,b,u,v,op;
}one[M+N],two[M+N],edge[M+N];
int m,n,q,cnt,tim,tot,top1,top2,fa[N],siz[N],disa[N],disb[N],vala[N],valb[N];
inline int gi(){
    RG int x=0;RG char c=getchar();
    while(c<‘0‘||c>‘9‘) c=getchar();
    while(c>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘,c=getchar();
    return x;
}
inline bool cmp1(RG const node &a,RG const node &b){
    if(a.a==b.a){
    if(a.b==b.b)
        return a.op<b.op;
    return a.b<b.b;
    }
    return a.a<b.a;
}
inline bool cmp2(RG const node &a,RG const node &b){
    if(a.b==b.b){
    if(a.a==b.a)
        return a.op<b.op;
    return a.a<b.a;
    }
    return a.b<b.b;
}
inline int find(RG int x){
    if(fa[x]==x) return x;
    return find(fa[x]);
}
inline int join(RG int u,RG int v,RG int a,RG int b,RG bool op){
    RG int fau=find(u),fav=find(v);
    if(!op){
    disa[fau]=max(a,disa[fau]);
    disb[fau]=max(b,disb[fau]);
    disa[fav]=max(a,disa[fav]);
    disb[fav]=max(b,disb[fav]);
    }
    else{
    sta[++tim].u=fau;
    sta[tim].v=fav;
    sta[tim].op=0;
    vala[fau]=max(a,vala[fau]);
    valb[fau]=max(b,valb[fau]);
    vala[fav]=max(a,vala[fav]);
    valb[fav]=max(b,valb[fav]);
    }
    if(fau==fav) return tim;
    sta[tim].op=1;
    if(siz[fau]>siz[fav]){
    fa[fav]=fau;
    siz[fau]+=siz[fav];
    if(!op){
        disa[fau]=max(disa[fau],disa[fav]);
        disb[fau]=max(disb[fau],disb[fav]);
    }
    else{
        swap(sta[tim].u,sta[tim].v);
        vala[fau]=max(vala[fau],vala[fav]);
        valb[fau]=max(valb[fau],valb[fav]);
    }
    }
    else{
    fa[fau]=fav;
    siz[fav]+=siz[fau];
    if(!op){
        disa[fav]=max(disa[fau],disa[fav]);
        disb[fav]=max(disb[fau],disb[fav]);
    }
    else{
        vala[fav]=max(vala[fau],vala[fav]);
        valb[fav]=max(valb[fau],valb[fav]);
    }
    }
    return tim;
}
inline void del(RG int x){
    if(sta[x].op){
    siz[sta[x].v]-=siz[sta[x].u];
    fa[sta[x].u]=sta[x].u;
    }
    vala[sta[x].u]=vala[sta[x].v]=valb[sta[x].u]=valb[sta[x].v]=-1;
}
int main(){
    freopen("multiple.in","r",stdin);
    freopen("multiple.out","w",stdout);
    n=gi();m=gi();
    for (RG int i=1;i<=m;++i){
    edge[i].u=gi();edge[i].v=gi();
    edge[i].a=gi();edge[i].b=gi();
    }
    q=gi();
    cnt=sqrt(m+q);
    tot=(m+q)/cnt+((m+q)%cnt>0);
    //printf("%d %d\n",cnt,tot);
    for (RG int i=1;i<=q;++i){
    edge[i+m].op=i;
    edge[i+m].u=gi();edge[i+m].v=gi();
    edge[i+m].a=gi();edge[i+m].b=gi();
    }
    sort(edge+1,edge+m+q+1,cmp1);
    //for (RG int i=1;i<=m+q;++i)
    //  printf("%d %d %d %d %d\n",edge[i].a,edge[i].b,edge[i].u,edge[i].v,edge[i].op);
    for (RG int i=1;i<=tot;++i){
    top1=top2=0;
    for (RG int j=1;j<=n;++j){
        fa[j]=j;siz[j]=1;
        disa[j]=disb[j]=-1;
    }
    for (RG int j=1;j<=min(i*cnt,m+q);++j)
        if(j<=(i-1)*cnt){
        if(!edge[j].op)
            one[++top1]=edge[j];
        }
        else if(edge[j].op)
        one[++top1]=edge[j];
        else
        two[++top2]=edge[j];
    sort(one+1,one+top1+1,cmp2);
    for (RG int j=1;j<=top1;++j){
        if(!one[j].op) join(one[j].u,one[j].v,one[j].a,one[j].b,0);
        else{
        tim=0;
        for (RG int k=1;k<=top2;++k)
            if(two[k].a<=one[j].a&&two[k].b<=one[j].b)
            two[k].op=join(two[k].u,two[k].v,two[k].a,two[k].b,1);
        RG int fau=find(one[j].u),fav=find(one[j].v);
        if(one[j].op==36){
            printf("%d %d %d %d %d %d\n",fau,fav,one[j].a,max(disa[fau],vala[fau]),one[j].b,max(disb[fau],valb[fau]));
        //  for (RG int i=1;i<=n;++i) printf("%d ",fa[i]);
        //  cout<<endl;
        }
        if(fau==fav&&max(disa[fau],vala[fau])==one[j].a&&max(disb[fau],valb[fau])==one[j].b)
            ans[one[j].op]=1;
        for (RG int k=top2;k;--k)
            if(two[k].a<=one[j].a&&two[k].b<=one[j].b)
            del(two[k].op);
        }
    }
    }
    for (RG int i=1;i<=q;++i)
    if(ans[i]) printf("Yes\n");
    else       printf("No\n");
    return 0;
}
时间: 2024-10-06 12:52:20

2017.7.22 hnoi2016 最小公倍数的相关文章

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

4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1687  Solved: 607[Submit][Status][Discuss] Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b 的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你求出是否存在一条顶点u到v之间的路径,使得 路径依次经过的边上的权值的最

BZOJ 4537: [Hnoi2016]最小公倍数

4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1084  Solved: 400[Submit][Status][Discuss] Description 给定一张N个顶点M条边的无向图(顶点编号为1,2,…,n),每条边上带有权值.所有权值都可以分解成2^a*3^b的形式.现在有q个询问,每次询问给定四个参数u.v.a和b,请你求出是否存在一条顶点u到v之间的路径,使得路径依次经过的边上的权值的最小公

【第三组】冲刺会议 2017.7.22

冲刺会议 日期:2017.7.22 开发小组:Geomestry 冲刺经理:程立智 成员: 程立智 李明伦 郑昊 蔡镇泽 温志成 汪涵 成员:程立智 完成工作:完成一键还原 所遇问题: 全屏设置有bug 下一步工作:完善选关界面 成员:李明伦 完成工作:修改关卡类 所遇问题:无 下一步工作:实例化关卡类 成员:郑昊 完成工作:画磁贴,画初始界面 所遇问题:无法判断用户分辨率的缩放 下一步工作:继续实现UI大小自适应 成员:蔡镇泽 完成工作: 直线功能的实现 所遇问题: 直线无法拖动画出 下一步工

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

[BZOJ4537][Hnoi2016]最小公倍数 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:P

2017.12.22 2周5次课

2017.12.22 二周第五次课 2.23/2.24/2.25 find命令 2.26 文件名后缀 2.23/2.24/2.25 find命令 1.学会使用快捷键 1)ctrl+C:结束(终止)当前命令.如果你输人了一大串字符,但不想运行,可以按ctrl+C组合键,此时光标将跳入下一行,而在刚刚的光标处会留下一个^C的标记. 2)Tab:实现自动补全功能.这个键比较重要,使用频率也很高.当你输人命令.文件或目录的前几个字符时,它会自动帮你补全. 3)ctrl+D:退出当前终端.同样,你也可以输

4537: [Hnoi2016]最小公倍数

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<

[题解]LCA练习+部分算法复习 2017.1.22

第一题就LCA即可.不过推荐用Tarjan(最快,常数很小).然后Tarjan的时候顺便就出一个dist[i],表示i节点到根节点的距离.求出了LCA,那么两点间的距离就为dist[u] + dist[v] - 2 * dist[lca]. Code 1 #include<iostream> 2 #include<sstream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstdlib> 6

2017/1/22

机器人搬重物 (robot.cpp/c/pas) 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6 米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M 的网格, 有些格子为不可移动的障碍.机器人的中心总是在格点上,当然,机器人必须在最短的时间 内把物品搬运到指定的地方.机器人接受的指令有:先前移动1 步(Creep):向前移动2 步(Walk ):向前移动3 步(Run):向左转(Left):向右转(Right).每个指令所需要的时 间为1

2017.09.22

刚刚下课,无心学习.想随便写点东西--今天,下雨了,不知道22年前的今天是否也在下雨呢?不过一场秋雨一场寒倒是真的,下去洗完澡去上课,湿漉漉的马路,湿漉漉的我,感觉风至吹头皮--幸好拿了伞.今天就吃了一顿饭(没有吃面条有点遗憾),不过我有许愿啊,虽然不知道会不会实现... 上课YQ老师一直举例子,我就莫名想起上通信原理的那些日子,W老师也是这样,我也最愿意上他的课了,可是现在喜欢的课没有了,连熟悉的老师面庞也并不能看到了.上个星期回了一次学校,恰巧碰见所有老师在开会,我一进去,那感觉就像嫁出去的