1. 程式人生 > >loj2048 「HNOI2016」最小公倍數

loj2048 「HNOI2016」最小公倍數

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」最小公倍數