loj2048 「HNOI2016」最小公倍数

这竟然是一道分块题……

#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
":"No
");
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/8963012.html