# 4537: [Hnoi2016]最小公倍数

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=2e5+5;
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}

int n, m, Q, u, v, x, y, block, bn, top, ans[N];
struct meow {
int u, v, a, b, id;
inline void print() {printf("%d %d %d %d\n", u, v, a, b);}
} e[N], q[N], a[N];
inline bool cmpa(const meow &a, const meow &b) {return a.a == b.a ? a.b < b.b : a.a < b.a;}
inline bool cmpb(const meow &a, const meow &b) {return a.b == b.b ? a.a < b.a : a.b < b.b;}

namespace ufs {
struct meow{int fa, maxa, maxb, size;} t[N];
struct info{int x, y; meow a, b; } st[N];
inline int find(int x) {return x == t[x].fa ? x : find(t[x].fa);}
inline void ini() {for(int i=1; i<=n; i++) t[i] = (meow){i, -1, -1, 1}; }
int x = find(e[id].u), y = find(e[id].v);
st[++top] = (info){x, y, t[x], t[y]};
if(x==y) {
t[x].maxa = max(t[x].maxa, e[id].a);
t[x].maxb = max(t[x].maxb, e[id].b);
return;
}
if(t[x].size < t[y].size) swap(x, y);
t[y].fa = x;
t[x].maxa = max(max(t[y].maxa, t[x].maxa), e[id].a);
t[x].maxb = max(max(t[y].maxb, t[x].maxb), e[id].b);
t[x].size += t[y].size;
}
inline void recov() {
t[ st[top].x ] = st[top].a, t[ st[top].y ] = st[top].b;
top--;
}
inline bool check(int id) {
int x = find(a[id].u), y = find(a[id].v);
//printf("check %d  %d %d  %d %d  %d\n", id, x, y, t[x].maxa, t[x].maxb, t[x].size);
return x == y && t[x].maxa == a[id].a && t[x].maxb == a[id].b;
}
} using ufs::st;

void solve() {
sort(e+1, e+m+1, cmpa); sort(q+1, q+Q+1, cmpa);
block = sqrt(m); bn = (m-1)/block+1;
for(int i=1; i<=bn; i++) { //printf("\n---------- %d\n", i);
int l = (i-1)*block+1, r = i==bn ? m : i*block;  //printf("[%d, %d]\n", l, r);
int p=0;
for(int i=1; i<=Q; i++)
if(q[i].a >= e[l].a && (r==m || q[i].a < e[r+1].a) ) a[++p] = q[i];

sort(e+1, e+l, cmpb); sort(a+1, a+p+1, cmpb);
//for(int i=1; i<=p; i++) a[i].print();
int now=1;
ufs::ini();
for(int i=1; i<=p; i++) {
while(now < l && e[now].b <= a[i].b) ufs::link(now), now++;
top=0;
for(int j=l; j<=r; j++)
if(e[j].a <= a[i].a && e[j].b <= a[i].b) ufs::link(j);// printf("j %d\n", j);
ans[ a[i].id ] = ufs::check(i);
while(top) ufs::recov();
}
}
for(int i=1; i<=Q; i++) puts(ans[i] ? "Yes" : "No");
}
int main() {
//freopen("in", "r", stdin);
freopen("multiple.in", "r", stdin);
freopen("multiple.out", "w", stdout);
solve();
}


posted @ 2017-04-10 23:03  Candy?  阅读(292)  评论(0编辑  收藏  举报