| 记录编号 |
256143 |
评测结果 |
TTTTTTTTTT |
| 题目名称 |
2291.[HZOI 2015]火龙果 |
最终得分 |
0 |
| 用户昵称 |
stdafx.h |
是否通过 |
未通过 |
| 代码语言 |
C++ |
运行时间 |
100.003 s |
| 提交时间 |
2016-04-29 12:15:07 |
内存使用 |
5.43 MiB |
显示代码纯文本
#define maxb 20ul
#define maxn 60010ul
#include <stdio.h>
#include <algorithm>
struct pii{int x,y;};
struct Edge{int u,v,a,b,c;}edge[maxn];
struct opr{int u,v,a,b,id;}op[maxn];
int n,m,q,vl[maxn],sta[maxn],seq[maxn],ms[maxn],tp[maxn],fa[maxn],ans[maxn],ch[maxn][2],mb[maxn];
bool tag[maxn];
pii ap[maxn];
const int inf=0x7fffffff;
#define L(e) ch[e][0]
#define R(e) ch[e][1]
void giverev(int x){
if(!x) return;
tag[x]^=1;
std::swap(L(x),R(x));
return;
}
inline void update(int x){
mb[x]=x>n?x-n:0;
if(L(x)&&edge[mb[L(x)]].b>edge[mb[x]].b) mb[x]=mb[L(x)];
if(R(x)&&edge[mb[R(x)]].b>edge[mb[x]].b) mb[x]=mb[R(x)];
return;
}
bool isroot(int x){
return (!fa[x])||(L(fa[x])!=x&&R(fa[x])!=x);
}
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;
else if(R(fa[x])==x) R(fa[x])=y;
fa[y]=fa[x],fa[x]=y;
update(x);return;
}
void pushdown(int x){
if(tag[x]){
giverev(L(x));
giverev(R(x));
tag[x]=false;
}
return;
}
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;
}
void access(int x){
int t=0;
while(x){
splay(x);pushdown(x);
R(x)=t;update(x);
t=x,x=fa[x];
}
return;
}
void makeroot(int x){
access(x);splay(x);
giverev(x);return;
}
void link(int x,int y){
makeroot(x),fa[x]=y;
return;
}
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;
}
int dfs(int x){
pushdown(x);
return L(x)?dfs(L(x)):x;
}
int find(int x){
access(x),splay(x);
return dfs(x);
}
int query(int u,int v){
if(find(u)!=find(v)) return 0;
makeroot(u),access(v),splay(v);
return mb[v];
}
int add_edge(int d){
int k=query(edge[d].u,edge[d].v);
if(k&&edge[k].b<=edge[d].b) 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;
}
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;
}
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;
}
bool cmp_with_a(const Edge &a,const Edge &b){return a.a<b.a;}
bool cmp2_with_a(const opr &a,const opr &b){return a.a<b.a;}
void divide(int l,int r,int ml,int mr,int ql,int qr,pii *rb){//<=mid
if(l>r||ml>mr||ql>qr) return;
int tot=0,mid=(l+r)>>1,qla=ql,qlb=ql,mla=ml,mlb=ml,px,pc;
for(int i=ql,j=ml,mx,qx,k;i<=qr;i++){
qx=seq[i];
while(j<=mr){
mx=ms[j];
if(edge[mx].c<=mid&&edge[mx].a<=op[qx].a){
if((k=add_edge(mx))!=-1) rb[++tot]=(pii){k,mx};
++j;
}
else if(edge[mx].a>op[qx].a) break;
else ++j;
}
k=query(op[qx].u,op[qx].v);
if(k&&edge[k].b<=op[qx].b) ans[op[qx].id]=mid,++qlb;
}
pc=qlb;
for(int i=ql;i<=qr;i++){
if(ans[op[seq[i]].id]<=mid) tp[qla++]=seq[i];
else tp[qlb++]=seq[i];
}
for(int i=ql;i<=qr;i++) seq[i]=tp[i];
for(int i=ml;i<=mr;i++) if(edge[ms[i]].c<=mid) ++mlb;
px=mlb;
for(int i=ml;i<=mr;i++){
if(edge[ms[i]].c<mid) tp[mla++]=ms[i];
else if(edge[ms[i]].c>mid) tp[mlb++]=ms[i];
}
for(int i=ml;i<=mr;i++) ms[i]=tp[i];
divide(mid+1,r,px,mlb-1,pc,qlb-1,rb+tot+1);
for(int i=1;i<=tot;i++) reb(rb[i].x,rb[i].y);
divide(l,mid-1,ml,mla-1,ql,qla-1,rb);
return;
}
int main(){
freopen("Dragon_fruit.in","r",stdin);
freopen("Dragon_fruit.out","w",stdout);
read(n),read(m),read(q);int mx=-1;
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);
for(int i=1;i<=m;i++) if(edge[i].c>mx) mx=edge[i].c;
std::sort(edge+1,edge+m+1,cmp_with_a);
for(int i=1;i<=m;i++) vl[i]=edge[i].b;
for(int i=1;i<=n+m;i++) update(i);
for(int i=1;i<=q;i++) read(op[i].u),read(op[i].v),read(op[i].a),read(op[i].b),op[i].id=i;
for(int i=1;i<=q;i++) ans[i]=inf;
std::sort(op+1,op+q+1,cmp2_with_a);
for(int i=1;i<=q;i++) seq[i]=i;
for(int i=1;i<=m;i++) ms[i]=i;
divide(1,mx,1,m,1,q,ap);
for(int i=1;i<=q;i++) if(ans[i]>mx) ans[i]=-1;
for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
return 0;
}