• [BZOJ4537]最小公倍数


    容易想到对于每一个询问,将所有a<=A&&b<=B的边加入,用并查集维护联通性,并且维护联通块中a,b的最大值,

    最后判断u,v是否联通并且a,b 的最大值是否等于A,B即可

    因为不要求是简单路径,所以这样做是可行的

    然后对于多个询问我们可以对边按a值分块

    对于每个块,选出属于该块的询问,即A值在该块内的询问

    对询问按b值排序

    对于之前所有块和当前块也分别按b值排序

    排序之后,对于之前所有块a值都满足要求,所以只要判断b值是否满足当前询问,若满足,加入并查集即可

    然后对于当前块内的边同理

    但当前块中满足这一个询问的边的a未必满足下一条询问,于是我们还要在并查集中删边

    于是我们使用不带路径压缩的启发式合并并查集

    使b值有序可以使用归并排序

    还有还有,,,自己到自己不存在最小公倍数,于是维护联通块a,b最大值的数组初值应赋为-1

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define fir first
      4 #define sec second
      5 #define mp make_pair
      6 #define pb push_back
      7 #define inf 0x3f3f3f3f
      8 #define maxn 50005
      9 #define maxm 100005
     10 struct node{ int u,v,ic,id,a,b; }R[maxm],Q[maxn];
     11 int n,m,q,ans[maxn],fa[maxn],sz[maxn],mx[maxn][2];
     12 vector<int>blc,haha;
     13 vector<pair<int,int> >rng;
     14 vector<node>cur,lst,tmp,op;
     15 int read(){
     16     int ttt=0; char ch=0;
     17     while(ch<'0'||ch>'9')ch=getchar();
     18     while(ch>='0'&&ch<='9')ttt=ttt*10+ch-'0',ch=getchar();
     19     return ttt;
     20 }
     21 bool cmp1(node x,node y){ return x.a<y.a; }
     22 bool cmp2(node x,node y){ return x.b<y.b; }
     23 void getblock(){
     24     sort(R+1,R+1+m,cmp1);
     25     int ele=sqrt(m);
     26     for(int i=1;i<=m;i++)
     27         blc.pb(R[min(i+=ele-1,m)].a);
     28     blc.pop_back(),blc.pb(inf);
     29     sort(Q+1,Q+1+q,cmp1);
     30     int j=1;
     31     for(int i=0;i<(int)blc.size();i++){
     32         int bf=j;
     33         while(j<=q&&Q[j].a<blc[i])j++;
     34         rng.pb(mp(bf,j-1));
     35     }
     36 }
     37 int gf(int x){    return fa[x]==x?x:gf(fa[x]); }
     38 void un(node P,int flag){
     39     int u=gf(P.u),v=gf(P.v);
     40     if(u!=v){
     41         if(sz[u]<sz[v]){
     42             if(flag)op.pb((node){u,v,sz[u],sz[v],mx[v][0],mx[v][1]});
     43             fa[u]=v,sz[v]+=sz[u];
     44             mx[v][0]=max(max(mx[u][0],mx[v][0]),P.a);
     45             mx[v][1]=max(max(mx[u][1],mx[v][1]),P.b);
     46         }
     47         else{
     48             if(flag)op.pb((node){u,v,sz[u],sz[v],mx[u][0],mx[u][1]});
     49             fa[v]=u,sz[u]+=sz[v];
     50             mx[u][0]=max(max(mx[u][0],mx[v][0]),P.a);
     51             mx[u][1]=max(max(mx[u][1],mx[v][1]),P.b);
     52         }
     53     }
     54     else{
     55         if(flag)op.pb((node){u,v,sz[u],sz[v],mx[u][0],mx[u][1]});
     56         mx[u][0]=max(max(mx[u][0],mx[v][0]),P.a);
     57         mx[u][1]=max(max(mx[u][1],mx[v][1]),P.b);
     58     }
     59 }
     60 void baoliun(int x){
     61     for(int i=0;i<(int)cur.size()&&cur[i].b<=Q[x].b;i++)
     62             if(cur[i].a<=Q[x].a)un(cur[i],1);
     63 }
     64 void baolibk(){
     65     for(int i=(int)op.size()-1;i>=0;i--){
     66         int u=op[i].u,v=op[i].v;
     67         fa[u]=u,fa[v]=v;
     68         sz[u]=op[i].ic,sz[v]=op[i].id;
     69         if(sz[u]<sz[v])mx[v][0]=op[i].a,mx[v][1]=op[i].b;
     70         else mx[u][0]=op[i].a,mx[u][1]=op[i].b;
     71     }
     72     op.clear();
     73 }
     74 void merge(){    
     75     tmp=lst,lst.clear();
     76     int i=0,j=0;
     77     while(i<(int)tmp.size()&&j<(int)cur.size()){
     78         if(tmp[i].b<cur[j].b)lst.pb(tmp[i++]);
     79         else lst.pb(cur[j++]);
     80     }
     81     while(i<(int)tmp.size())lst.pb(tmp[i++]);
     82     while(j<(int)cur.size())lst.pb(cur[j++]);
     83 }
     84 void getans(int l,int r){
     85     for(int i=1;i<=n;i++)fa[i]=i,sz[i]=1;
     86     memset(mx,-1,sizeof(mx));
     87     int j=0;
     88     for(int i=l;i<=r;i++){    
     89         while(j<(int)lst.size()&&lst[j].b<=Q[i].b)un(lst[j++],0);
     90         baoliun(i);
     91         int u=gf(Q[i].u),v=gf(Q[i].v);
     92         if(u==v&&mx[u][0]==Q[i].a&&mx[u][1]==Q[i].b)ans[Q[i].id]=1;
     93         baolibk();
     94     }
     95     merge();
     96 }
     97 void solve(){
     98     getblock();
     99     int j=1;
    100     for(int i=0;i<(int)blc.size();i++){
    101         cur.clear();
    102         while(j<=m&&R[j].a<=blc[i])cur.pb(R[j++]);
    103         sort(cur.begin(),cur.end(),cmp2);
    104         sort(Q+rng[i].fir,Q+rng[i].sec+1,cmp2);
    105         getans(rng[i].fir,rng[i].sec);
    106     }
    107 }
    108 int main(){
    109     n=read(),m=read();
    110     for(int i=1;i<=m;i++)
    111         R[i].u=read(),R[i].v=read(),R[i].a=read(),R[i].b=read();
    112     q=read();
    113     for(int i=1;i<=q;i++){
    114         Q[i].u=read(),Q[i].v=read(),Q[i].a=read(),Q[i].b=read();
    115         Q[i].id=i;
    116     }
    117     solve();
    118     for(int i=1;i<=q;i++)
    119         puts(ans[i]?"Yes":"No");
    120     return 0;
    121 }
    View Code
  • 相关阅读:
    LA 3026 Period
    Touch
    Uva 11762 Race to 1
    清北学堂模拟赛d1t2 火柴棒 (stick)
    清北学堂模拟赛d1t1 位运算1(bit)
    常州模拟赛d8t2 绘画
    常州模拟赛d8t1 友好数对
    常州模拟赛d5t3 appoint
    常州模拟赛d7t1 亲戚
    常州模拟赛d7t3 水管
  • 原文地址:https://www.cnblogs.com/Ngshily/p/5422601.html
Copyright © 2020-2023  润新知