• 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;
    }
    
  • 相关阅读:
    SQL综合练习(一)
    数据探索及数据处理&文本数据的处理(二)
    数据探索及数据处理&文本数据的处理(一)
    交叉验证cross_validation
    优惠券预测——特征工程
    优惠券预测——数据探索2
    优惠券预测——数据探索1
    C盘扩容
    tracert在网络中的使用
    网络故障篇
  • 原文地址:https://www.cnblogs.com/poorpool/p/8963012.html
Copyright © 2020-2023  润新知