QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#141151 | #6847. Hide-And-Seek Game | wu6789 | AC ✓ | 41ms | 1876kb | C++14 | 3.4kb | 2023-08-17 09:01:55 | 2023-08-17 09:01:58 |
Judging History
answer
#include<cstdio>
#include<algorithm>
#include<cmath>
#define M 5005
using namespace std;
struct E{
int to,nx;
}edge[M<<1];
int tot,head[M];
void Addedge(int a,int b){
edge[++tot].to=b;
edge[tot].nx=head[a];
head[a]=tot;
}
int sz[M],son[M],top[M],dep[M];
int Dfn[M],Low[M],tot_dfs;
int fa[M];
void dfs(int now){
Dfn[now]=++tot_dfs;
sz[now]=1;son[now]=0;
for(int i=head[now];i;i=edge[i].nx){
int nxt=edge[i].to;
if(nxt==fa[now])continue;
fa[nxt]=now;
dep[nxt]=dep[now]+1;
dfs(nxt);
sz[now]+=sz[nxt];
if(sz[son[now]]<sz[nxt])son[now]=nxt;
}
Low[now]=tot_dfs;
}
void dfs_top(int now){
if(son[now]){
top[son[now]]=top[now];
dfs_top(son[now]);
}
for(int i=head[now];i;i=edge[i].nx){
int nxt=edge[i].to;
if(nxt==fa[now]||nxt==son[now])continue;
top[nxt]=nxt;
dfs_top(nxt);
}
}
int LCA(int a,int b){
while(top[a]!=top[b]){
if(dep[top[a]]<dep[top[b]])b=fa[top[b]];
else a=fa[top[a]];
}
return dep[a]<dep[b]?a:b;
}
bool In(int x,int y){
return Dfn[y]<=Dfn[x]&&Dfn[x]<=Low[y];
}
int mark[M];
struct Point{
int a,b;
};
Point Data[M][2];
int exgcd(int a,int b,int &x,int &y){
int d=a; if(b==0) x=1,y=0; else{
d=exgcd(b,a%b,y,x),y-=a/b*x;
}
return d;
}
int Get_ans(Point p1,Point p2){
int val=p2.b-p1.b;
val%=p2.a;
while(val<0)val+=p2.a;
while(val>p2.a)val-=p2.a;
int a=p1.a,b=-p2.a;
int x,y,d=exgcd(a,b,x,y);
if(val%d!=0)return 1e9;
x*=val/d;y*=val/d;
int p=b/d,q=a/d;
if(x<0){
int k=ceil((1.0-x)/p);
x+=p*k,y-=q*k;
}else if(x>=0){
int k=(x-1)/p;
x-=p*k,y+=q*k;
}
return a*x+p1.b;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,m;
tot=0;
scanf("%d%d",&n,&m);
tot_dfs=0;
for(int i=1;i<=n;i++)head[i]=mark[i]=0;
for(int i=1;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
Addedge(a,b);
Addedge(b,a);
}
dfs(1);
top[1]=1;
dfs_top(1);
for(int step=1;step<=m;step++){
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
if(a==c){printf("%d\n",a);continue;}
int x1=LCA(a,b),x2=LCA(c,d);
if(dep[x1]>dep[x2]){
swap(a,c);
swap(b,d);
swap(x1,x2);
}
if(!In(a,x2)&&!In(b,x2)){
puts("-1");
continue;
}
int d1=dep[a]+dep[b]-2*dep[x1],d2=dep[c]+dep[d]-2*dep[x2];
int p=a;
while(1){
Data[p][0]=(Point){2*d1,dep[a]-dep[p]};
Data[p][1]=(Point){2*d1,2*d1-(dep[a]-dep[p])};
mark[p]=step;
if(p==x1)break;
p=fa[p];
}
p=b;
while(p!=x1){
Data[p][0]=(Point){2*d1,d1-(dep[b]-dep[p])};
Data[p][1]=(Point){2*d1,d1+(dep[b]-dep[p])};
mark[p]=step;
p=fa[p];
}
int ans_val=1e9,ans=-1;
p=c;
while(1){
Point p1=(Point){2*d2,dep[c]-dep[p]};
Point p2=(Point){2*d2,2*d2-(dep[c]-dep[p])};
if(mark[p]==step){
int res=1e9;
res=min(min(Get_ans(p1,Data[p][0]),Get_ans(p1,Data[p][1])),min(Get_ans(p2,Data[p][0]),Get_ans(p2,Data[p][1])));
if(res<ans_val){
ans_val=res;
ans=p;
}
}
if(p==x2)break;
p=fa[p];
}
p=d;
while(p!=x2){
Point p1=(Point){2*d2,d2-(dep[d]-dep[p])};
Point p2=(Point){2*d2,d2+(dep[d]-dep[p])};
if(mark[p]==step){
int res=1e9;
res=min(min(Get_ans(p1,Data[p][0]),Get_ans(p1,Data[p][1])),min(Get_ans(p2,Data[p][0]),Get_ans(p2,Data[p][1])));
if(res<ans_val){
ans_val=res;
ans=p;
}
}
p=fa[p];
}
printf("%d\n",ans);
}
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 41ms
memory: 1876kb
input:
500 6 20 1 2 1 3 3 4 2 5 3 6 1 6 6 5 2 1 6 2 5 1 2 6 2 6 1 2 6 3 6 4 4 1 1 3 5 6 3 4 2 1 3 5 2 4 1 2 6 2 1 2 6 2 1 4 1 6 1 6 2 5 2 6 2 5 6 2 5 2 1 3 5 6 6 4 4 1 4 5 5 4 4 1 3 6 1 2 6 1 4 3 71 30 1 2 2 3 2 4 4 5 2 6 6 7 4 8 2 9 1 10 9 11 3 12 5 13 5 14 10 15 6 16 13 17 17 18 4 19 5 20 17 21 20 22 4 2...
output:
3 -1 -1 -1 6 3 -1 1 -1 1 3 1 2 -1 -1 3 4 1 -1 3 -1 11 2 -1 5 -1 17 -1 -1 5 -1 -1 -1 -1 2 -1 5 53 5 7 -1 -1 2 4 -1 -1 -1 -1 -1 -1 -1 5 -1 1 5 1 -1 -1 -1 -1 33 5 1 1 -1 1 -1 -1 -1 -1 7 -1 -1 9 5 3 -1 -1 -1 19 -1 -1 6 5 -1 -1 5 -1 -1 -1 -1 1 -1 7 -1 -1 1 -1 -1 -1 8 -1 13 -1 -1 -1 -1 4 5 -1 -1 5 -1 -1 8...
result:
ok 53199 lines