BZOJ 4537: [Hnoi2016]最小公倍数

http://www.cnblogs.com/clrs97/p/5406018.html

Claris好劲啊

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=100000+5;
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
struct Edge{int u,v,a,b;}e[N],q[N];
bool cmpe(int i,int j){return e[i].b<e[j].b;}
bool cmpq(int i,int j){return q[i].b<q[j].b;}
bool cmp(Edge i,Edge j){return i.a<j.a;}
int pa[N],va[N],vb[N],rank[N];
int find(int x){return pa[x]==x?x:find(pa[x]);}
struct opt{int k,a,b;}op[N<<1];
int tot;
void merge(Edge e,bool flag){
	e.u=find(e.u);e.v=find(e.v);
	if(e.u!=e.v){
		if(rank[e.u]==rank[e.v]){
			if(flag)op[++tot]=(opt){4,e.v,rank[e.v]};
			rank[e.v]++;
		}
		if(rank[e.v]<rank[e.u])swap(e.u,e.v);
		if(flag)op[++tot]=(opt){1,e.u,pa[e.u]};
		pa[e.u]=e.v;
		if(va[e.u]>va[e.v]&&va[e.u]>e.a){
			if(flag)op[++tot]=(opt){2,e.v,va[e.v]};
			va[e.v]=va[e.u];
		}
		if(vb[e.u]>vb[e.v]&&vb[e.u]>e.b){
			if(flag)op[++tot]=(opt){3,e.v,vb[e.v]};
			vb[e.v]=vb[e.u];
		}
	}
	if(e.a>va[e.v]){if(flag)op[++tot]=(opt){2,e.v,va[e.v]};va[e.v]=e.a;}
	if(e.b>vb[e.v]){if(flag)op[++tot]=(opt){3,e.v,vb[e.v]};vb[e.v]=e.b;}
}
void retrace(){
	per(i,tot,1)
	if(op[i].k==1)pa[op[i].a]=op[i].b;
	else if(op[i].k==2)va[op[i].a]=op[i].b;
	else if(op[i].k==3)vb[op[i].a]=op[i].b;
	else rank[op[i].a]=op[i].b;
	tot=0;
}
int read(){char ch=getchar();int x=0,f=1;while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
bool ans[N];
int p[N],r[N];
int main(){
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);
	int n,m;n=read();m=read();
	rep(i,1,m)e[i].u=read(),e[i].v=read(),e[i].a=read(),e[i].b=read(),r[i]=i;
	sort(e+1,e+1+m,cmp);
	int k=read();
	rep(i,1,k)q[i].u=read(),q[i].v=read(),q[i].a=read(),q[i].b=read();
	int blk=sqrt(m+0.5);
	for(int st=0;st<=m;st+=blk){
		int cnt=0;
		rep(i,1,k)if(e[st].a<=q[i].a&&(st+blk>m||q[i].a<e[st+blk].a))p[++cnt]=i;
		if(!cnt)continue;
		sort(r+1,r+1+st,cmpe);sort(p+1,p+1+cnt,cmpq);
		rep(i,1,n)pa[i]=i,va[i]=vb[i]=-1,rank[i]=0;
		int j=1;
		rep(i,1,cnt){
			while(j<=st&&e[r[j]].b<=q[p[i]].b)
			merge(e[r[j++]],0);
			tot=0;
			per(t,min(st+blk-1,m),st+1)
			if(e[t].a<=q[p[i]].a&&e[t].b<=q[p[i]].b)
			merge(e[t],1);
			int u=find(q[p[i]].u),v=find(q[p[i]].v);
			if(u==v&&va[u]==q[p[i]].a&&vb[u]==q[p[i]].b)ans[p[i]]=1;
			retrace();
		}
	}
	rep(i,1,k)puts(ans[i]?"Yes":"No");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值