记录编号 256212 评测结果 AAAAAAAAAA
题目名称 [HZOI 2015]火龙果 最终得分 100
用户昵称 Gravatarstdafx.h 是否通过 通过
代码语言 C++ 运行时间 31.711 s
提交时间 2016-04-29 16:22:07 内存使用 4.72 MiB
显示代码纯文本
#define maxb 180ul
#define maxn 60010ul

#include <math.h>
#include <vector>
#include <stdio.h>
#include <algorithm>

#define fastcall __attribute__((optimize("-O3")))
#define IL __inline__ __attribute__((always_inline))

#define pb push_back

#define L(e) ch[e][0]
#define R(e) ch[e][1]

struct pii{int x,y;}st[maxn];
struct Edge{int u,v,a,b,c;}edge[maxn];
struct opr{int u,v,a,b;}op[maxn];

const int inf=0x7fffffff;

int n,m,q,tot,mxa,bcnt,bsiz,sta[maxn],fa[maxn],mc[maxn],ch[maxn][2],ans[maxn],bls[maxn],all[maxn];
bool tag[maxn];
std::vector<int> G[maxb],Q[maxb];

fastcall IL void read(int &x){
	x=0;int c=getchar();
	while(c<'0'||c>'9') c=getchar();
	for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return;
}

fastcall IL void _swap(int &x,int &y){
	if(x!=y) x^=y,y^=x,x^=y;
	return;
}

fastcall IL void giverev(int x){
	if(!x) return;
	tag[x]^=1;
	_swap(L(x),R(x));
	return;
}

fastcall IL void update(int x){
	mc[x]=x>n?x-n:0;
	if(L(x)&&edge[mc[L(x)]].c>edge[mc[x]].c) mc[x]=mc[L(x)];
	if(R(x)&&edge[mc[R(x)]].c>edge[mc[x]].c) mc[x]=mc[R(x)];
	return;
}

fastcall IL bool isroot(int x){
	return (!fa[x])||(L(fa[x])!=x&&R(fa[x])!=x);
}

fastcall IL void rotate(int x,int d){
	int y=ch[x][d^1];
	ch[x][d^1]=ch[y][d];
	fa[ch[y][d]]=x,ch[y][d]=x;
	if(L(fa[x])==x) L(fa[x])=y;
	if(R(fa[x])==x) R(fa[x])=y;
	fa[y]=fa[x],fa[x]=y;
	update(x);return;
}

fastcall IL void pushdown(int x){
	if(tag[x]){
		giverev(L(x));
		giverev(R(x));
		tag[x]=false;
	}
	return;
}

fastcall IL void splay(int p){
	sta[++sta[0]]=p;
	for(int i=p;!isroot(i);i=fa[i]) sta[++sta[0]]=fa[i];
	while(sta[0]) pushdown(sta[sta[0]--]);
	int x,y;
	while(!isroot(p)){
		x=fa[p],y=fa[x];
		if(isroot(x)) rotate(x,L(x)==p);
		else{
			if((L(y)==x)==(L(x)==p)) rotate(y,L(y)==x),rotate(x,L(x)==p);
			else rotate(x,L(x)==p),rotate(y,L(y)==p);
		}
	}
	update(p);
	return;
}

fastcall IL void access(int x){
	int t=0;
	while(x){
		splay(x),pushdown(x);
		R(x)=t,update(x);
		t=x,x=fa[x];
	}
	return;
}

fastcall IL void makeroot(int x){
	access(x),splay(x);
	giverev(x);return;
}

fastcall IL int find(int x){
	access(x),splay(x),pushdown(x);
	while(L(x)) x=L(x),pushdown(x);
	return x;
}

fastcall IL void cut(int x,int y){
	makeroot(x),access(y),splay(y),pushdown(y);
	if(L(y)==x) fa[x]=L(y)=0;
	update(y);return;
}

fastcall IL void link(int x,int y){
	makeroot(x),fa[x]=y;
	return;
}

fastcall IL int query(int u,int v){
	if(find(u)!=find(v)) return 0;
	makeroot(u),access(v),splay(v);
	return mc[v];
}

fastcall IL bool qcmp(int a,int b){return op[a].b<op[b].b;}
fastcall IL bool ecmp(int a,int b){return edge[a].b<edge[b].b;}

fastcall IL void rp(int x){
	fa[x]=tag[x]=L(x)=R(x)=0;
	update(x);return;
}

fastcall int add_edge(int d){
	int k=query(edge[d].u,edge[d].v);
	if(k&&edge[k].c<=edge[d].c) return -1;
	if(k) cut(edge[k].u,k+n),cut(edge[k].v,k+n);
	link(edge[d].u,d+n),link(edge[d].v,d+n);
	return k;
}

fastcall void reb(int r,int nv){
	cut(edge[nv].u,nv+n),cut(edge[nv].v,nv+n);
	if(r) link(edge[r].u,r+n),link(edge[r].v,r+n);
	return;
}

fastcall void work(int b){
	int esize=G[b].size(),qsize=Q[b].size(),head=1;
	for(int i=1;i<=n+m;i++) rp(i);
	for(int i=0,j,x,y,t,top;i<qsize;i++){
		x=Q[b][i],top=0;
		while(head<=tot){
			t=all[head];
			if(edge[t].b>op[x].b) break;
			add_edge(t),++head;
		}
		for(j=0;j<esize;j++){
			y=G[b][j];
			if(edge[y].b>op[x].b) break;
			if(edge[y].a<=op[x].a&&(t=add_edge(y))!=-1) st[++top]=(pii){t,y};
		}
		t=query(op[x].u,op[x].v);
		if(t) ans[x]=edge[t].c;
		while(top) reb(st[top].x,st[top].y),--top;
	}
	return;
}

fastcall void add(int b){
	int esize=G[b].size();
	for(int i=0;i<esize;i++) all[++tot]=G[b][i];
	std::sort(all+1,all+tot+1,ecmp);
	return;
}

int main(){
	freopen("Dragon_fruit.in","r",stdin);
	freopen("Dragon_fruit.out","w",stdout);
	read(n),read(m),read(q);
	for(int i=1;i<=m;i++){
		read(edge[i].u),read(edge[i].v),read(edge[i].a),read(edge[i].b),read(edge[i].c);
		if(edge[i].a>mxa) mxa=edge[i].a;
	}
	for(int i=1;i<=q;i++){
		read(op[i].u),read(op[i].v),read(op[i].a),read(op[i].b),ans[i]=-1;
		if(op[i].a>mxa) mxa=op[i].a;
	}
	bsiz=sqrt(mxa);
	for(int i=1;i<=mxa;i++) bls[i]=(i-1)/bsiz+1;
	bcnt=bls[mxa];
	for(int i=1;i<=m;i++) G[bls[edge[i].a]].pb(i);
	for(int i=1;i<=q;i++) Q[bls[op[i].a]].pb(i);
	for(int i=1;i<=bcnt;i++) std::sort(G[i].begin(),G[i].end(),ecmp),std::sort(Q[i].begin(),Q[i].end(),qcmp);
	for(int i=1;i<=bcnt;i++) work(i),add(i);
	for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
	return 0;
}