# bzoj4537[HNOI2016]最小公倍数

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<ctime>
#define P puts("lala")
#define cp cerr<<"lala"<<endl
#define fi first
#define se second
#define ln putchar('\n')
#define pb push_back
#define shmem(x) cerr<<sizeof(x)/(1024*1024.0)<<"MB"<<endl
using namespace std;
{
char ch=getchar();int g=1,re=0;
while(ch<'0'||ch>'9'){if(ch=='-')g=-1; ch=getchar();}
while(ch<='9'&&ch>='0') re=(re<<1)+(re<<3)+(ch^48),ch=getchar();
return re*g;
}
typedef long long ll;
typedef pair<int,int> pii;

const int N=100050;
struct node
{
int x,y,a,b,id;
node(int x=0,int y=0,int a=0,int b=0,int id=0):x(x),y(y),a(a),b(b),id(id) { }
};
inline bool operator < (node a,node b) {return a.b<b.b;}
inline bool cmp1(node a,node b) {return a.a<b.a;}
inline bool cmp2(node a,node b) {return a.b<b.b;}
node e[N],q[N];
int n,m,blosiz,bel[N],Ans[N];
vector<node>ve[500];

int fa[N];
inline int find(int x)
{
while(fa[x]!=x) x=fa[x];
return x;
}
node stk[N]; int top=0;
int maxa[N],maxb[N],siz[N];
inline void merge(int x,int y,int a,int b)
{
x=find(x); y=find(y);
if(siz[x]>siz[y]) swap(x,y);
stk[++top]=node(x,y,maxa[y],maxb[y],siz[y]);
maxa[y]=max(maxa[y],max(maxa[x],a)); maxb[y]=max(maxb[y],max(maxb[x],b));
if(x==y) return ;
siz[y]+=siz[x]; fa[x]=y;
}
inline void undo()
{
int x=stk[top].x,y=stk[top].y;
siz[y]=stk[top].id; maxa[y]=stk[top].a; maxb[y]=stk[top].b;
fa[x]=x;
top--;
}

node now[N],tmp[N]; int tot=0;
void mergesort(int l,int r)
{
int p1=1,p2=l,p3=1;
while(p1<=tot&&p2<=r)
{
if(now[p1]<e[p2]) tmp[p3]=now[p1],p1++,p3++;
else tmp[p3]=e[p2],p2++,p3++;
}
while(p1<=tot) tmp[p3]=now[p1],p1++,p3++;
while(p2<=r) tmp[p3]=e[p2],p2++,p3++;
tot+=r-l+1;
for(int i=1;i<=tot;++i) now[i]=tmp[i];
}

int main()
{
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);freopen("1.out","w",stdout);
#endif
for(int i=1;i<=m;++i)
for(int i=1;i<=Q;++i)

sort(e+1,e+1+m,cmp1);
blosiz=sqrt(m);
for(int i=1;i<=m;++i) bel[i]=(i-1)/blosiz+1;

sort(q+1,q+1+Q,cmp1);
for(int i=1,p1=1;i<=m;++i)
{
while(p1<=Q&&(q[p1].a<e[i].a||i==m)) ve[bel[i]].pb(q[p1]),p1++;
}
for(int i=1;i<=bel[m];++i) sort(ve[i].begin(),ve[i].end());
for(int i=1;i<=bel[m];++i) sort(e+(i-1)*blosiz+1,e+min(i*blosiz,m)+1);

for(int o=1;o<=bel[m];++o)
{
top=0;
for(int i=1;i<=n;++i) fa[i]=i,maxa[i]=maxb[i]=-1,siz[i]=1;
int siz=ve[o].size(),p1=1;
for(int w=0;w<siz;++w)
{
while(p1<=tot&&ve[o][w].b>=now[p1].b) //in front of the block
merge(now[p1].x,now[p1].y,now[p1].a,now[p1].b),p1++;
int last=top;
for(int i=(o-1)*blosiz+1;i<=m&&i<=o*blosiz;++i) //in the block
if(e[i].b<=ve[o][w].b)
{
if(e[i].a<=ve[o][w].a)
merge(e[i].x,e[i].y,e[i].a,e[i].b);
}
else break;
int r1=find(ve[o][w].x),r2=find(ve[o][w].y);
if(r1==r2&&maxa[r1]==ve[o][w].a&&maxb[r1]==ve[o][w].b)
Ans[ve[o][w].id]=1;
while(top!=last) undo();
}
mergesort((o-1)*blosiz+1,min(o*blosiz,m));
}
for(int i=1;i<=Q;++i) puts(Ans[i]==1?"Yes":"No");
return 0;
}

posted @ 2018-03-17 22:09  BLMontgomery  阅读(101)  评论(0编辑  收藏  举报