zoukankan      html  css  js  c++  java
  • bzoj 4537 最小公倍数

    给定一张N个顶点M条边的无向图 每条边上带有权值 所有权值都可以分解成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,那么称路径为简单路径

    思路:

    对于每个询问(u,v,A,B),将a<=A和b<=B的边全部加入并查集中,最后判断u和v是否在同一连通分量中且连通分量包含的最大的a=A,最大的b=B即可

    把询问和边离线按a排序,询问时在已经加入的边中按b值排序加入并查集中

    结合起来,按a值将询问和边分块,前面的边按第二种做法做,块内的边按第一种做法做就行了

    因为并查集需要支持撤销,所以要用按秩合并
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 100100
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 int n,m,T,fa[MAXN],rnk[MAXN],f,pos,b,mxp[MAXN],mxq[MAXN],top,cnt,size,ans[MAXN];
    21 struct data
    22 {
    23     int u,v,p,q,pos;
    24     bool operator < (const data & a) const {return q<a.q||(q==a.q&&pos<a.pos);}
    25 }qs[MAXN],e[MAXN<<1],tmp[MAXN<<2];
    26 struct stck{int u,v,rnk,p,q;}st[MAXN<<1];
    27 int find(int x) {return x==fa[x]?x:find(fa[x]);}
    28 void merge(int u,int v,int p,int q)
    29 {
    30     int x=find(u),y=find(v);
    31     if(rnk[x]<rnk[y]) swap(x,y);
    32     st[++top]=(stck) {x,y,rnk[x],mxp[x],mxq[x]};
    33     fa[y]=x;
    34     mxp[x]=max(p,max(mxp[y],mxp[x]));
    35     mxq[x]=max(q,max(mxq[x],mxq[y]));
    36     if(rnk[x]==rnk[y]) rnk[x]++;
    37 }
    38 bool Cmp(data a,data b) {return a.p<b.p||(a.p==b.p&&a.q<b.q);}
    39 void dlt()
    40 {
    41     fa[st[top].v]=st[top].v,rnk[st[top].u]=st[top].rnk,mxp[st[top].u]=st[top].p,mxq[st[top].u]=st[top].q,top--;
    42 }
    43 int main()
    44 {
    45     //freopen("al.in","r",stdin);
    46     //freopen("al.out","w",stdout);
    47     n=read(),m=read();int x,y,tot=0;
    48     for(int i=1;i<=m;i++)
    49         e[i].u=read(),e[i].v=read(),e[i].p=read(),e[i].q=read(),e[i].pos=0;
    50     size=sqrt(m*2);
    51     sort(e+1,e+m+1,Cmp);
    52     T=read();
    53     for(int i=1;i<=T;i++)
    54         qs[i].u=read(),qs[i].v=read(),qs[i].p=read(),qs[i].q=read(),qs[i].pos=i;
    55     sort(qs+1,qs+T+1,Cmp);
    56     for(int i=1;i<=m;i++)
    57     {
    58         if((++tot==size)||i==m)
    59         {
    60             cnt=0;
    61             for(int j=1;j<=i-tot;j++) tmp[++cnt]=e[j];
    62             for(int j=1;j<=T;j++)
    63                 if(qs[j].p>=e[i-cnt+1].p&&(i==m||qs[j].p<e[i+1].p)) tmp[++cnt]=qs[j];
    64             if(i-tot!=cnt)
    65             {
    66                 for(int j=1;j<=n;j++) fa[j]=j,rnk[j]=0,mxp[j]=mxq[j]=-1;
    67                 sort(tmp+1,tmp+cnt+1);top=0;
    68                 for(int j=1;j<=cnt;j++)
    69                 {
    70                     if(tmp[j].pos)
    71                     {
    72                         for(int k=i-tot+1;k<=i+1;k++)
    73                         {
    74                             if(e[k].p>tmp[j].p||k>i)
    75                             {
    76                                 int x=find(tmp[j].u),y=find(tmp[j].v);
    77                                 if(x==y&&mxp[x]==tmp[j].p&&mxq[x]==tmp[j].q) ans[tmp[j].pos]=1;
    78                                 for(int l=i-tot+1;l<=k-1;l++) if(e[l].q<=tmp[j].q) dlt();
    79                                 break;
    80                             }
    81                             if(e[k].q<=tmp[j].q) merge(e[k].u,e[k].v,e[k].p,e[k].q);
    82                         }
    83                     }
    84                     else merge(tmp[j].u,tmp[j].v,tmp[j].p,tmp[j].q);
    85                 }
    86             }
    87             tot=0;
    88         }
    89     }
    90     for(int i=1;i<=T;i++)
    91         puts(ans[i]?"Yes":"No");
    92 }
    View Code
  • 相关阅读:
    JavaScript的离线存储——localStorage、sessionStorage以及cookie
    for循环中的异步处理(异步变同步)
    pc网站随鼠标滚动动态出现效果
    layui tab选项卡Hash地址的定位和跳转到指定tab栏
    scroll滚动监听实现animate返回顶部(有坑)
    Vue之使用elementUI的upload上传组件导入csv文件
    element+sortablejs插件实现拖拽排序效果
    超简单的jq图片上传
    取字符串中的汉字的俩种方式
    js获得url地址携带参数
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8435769.html
Copyright © 2011-2022 走看看