loj2048 「HNOI2016」最小公倍數
阿新 • • 發佈:2018-04-27
ios r+ printf 最小 struct node IT SQ cpp
這竟然是一道分塊題……
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, m, q, blc, qnt, fa[50005], mxa[50005], mxb[50005], sz[50005], bcj, ans[50005];
struct Node{
int uu, uv, ux, uy, uz;
}a[100005], b[50005], que[50005];
struct Bnode{
int aa, bb, cc, dd, ee, ff;
}bn[100005 ];
bool cma(const Node &x, const Node &y){
if(x.ux==y.ux) return x.uy<y.uy;
return x.ux<y.ux;
}
bool cmb(const Node &x, const Node &y){
if(x.uy==y.uy) return x.ux<y.ux;
return x.uy<y.uy;
}
int myfind(int x){
return fa[x]==x?x:myfind(fa[x]);
}
void merge(int uu, int uv, int uw, int ux){
uu = myfind(uu); uv=myfind(uv);
if(sz[uu]<sz[uv]) swap(uu, uv);
bn[++bcj] = (Bnode){uu, uv, fa[uv], sz[uu], mxa[uu], mxb[uu]};
if(uu==uv){
mxa[uu] = max(mxa[uu], uw);
mxb[uu] = max(mxb[uu], ux);
return ;
}
fa[uv] = uu; sz[uu] += sz[uv];
mxa[uu] = max(mxa[uu], max(mxa[uv], uw));
mxb[uu] = max(mxb[uu], max(mxb[uv], ux));
}
int main(){
cin>>n>>m;
blc = sqrt(m);
for(int i=1; i<=m; i++)
scanf("%d %d %d %d", &a[i].uu, &a[i].uv, &a[i].ux, &a[i].uy);
cin>>q;
for(int i=1; i<=q; i++){
scanf("%d %d %d %d", &b[i].uu, &b[i].uv, &b[i].ux, &b[i].uy);
b[i].uz = i;
}
sort(a+1, a+1+m, cma);
sort(b+1, b+1+q, cmb);
for(int i=1; i<=m; i+=blc){
qnt = 0;
for(int j=1; j<=q; j++)
if(b[j].ux>=a[i].ux && (i+blc>m || b[j].ux<a[i+blc].ux))
que[++qnt] = b[j];
int r=1;
for(int j=1; j<=n; j++){
fa[j] = j;
sz[j] = 1;
mxa[j] = mxb[j] = -1;
}
sort(a+1, a+i+1, cmb);
for(int j=1; j<=qnt; j++){
for(; r<i && a[r].uy<=que[j].uy; r++)
merge(a[r].uu, a[r].uv, a[r].ux, a[r].uy);
bcj = 0;
for(int k=i; k<i+blc && k<=m; k++)
if(a[k].ux<=que[j].ux && a[k].uy<=que[j].uy)
merge(a[k].uu, a[k].uv, a[k].ux, a[k].uy);
int x=myfind(que[j].uu), y=myfind(que[j].uv);
if(x==y && mxa[x]==que[j].ux && mxb[x]==que[j].uy)
ans[que[j].uz] = 1;
for(int i=bcj; i>=1; i--){
int xx=bn[i].aa, yy=bn[i].bb;
fa[yy] = bn[i].cc;
sz[xx] = bn[i].dd;
mxa[xx] = bn[i].ee; mxb[xx] = bn[i].ff;
}
}
}
for(int i=1; i<=q; i++)
printf(ans[i]?"Yes\n":"No\n");
return 0;
}
loj2048 「HNOI2016」最小公倍數