|
【题目大意】
一堆人在操场上跑步,他们都有一定的速度和初始位置,
当两个人相遇的时候编号较小的就会出局,当场上剩下最后一个人的时候游戏结束,
问时长为多少
【题解】
我们发现每次发生碰撞的一定是相邻的两个人,
所以我们找出相邻关系中最先发生碰撞的,将碰撞失败的那个人删除,
之后继续这个过程,
按照上述的做法我们建立一个循环链表,把所有人串起来,
当发生淘汰的时候把那个人从循环链表中删去即可,
用优先队列维护相邻关系,每次出队最小相遇时间即可。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <string.h>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <list>
#include <bitset>
#include <stack>
#include <stdlib.h>
#define lowbit(x) (x&-x)
#define e exp(1.0)
#define eps 1e-8
//ios::sync_with_stdio(false);
// auto start = clock();
// cout << (clock() - start) / (double)CLOCKS_PER_SEC<<endl;
typedef long long ll;
typedef long long LL;
using namespace std;
typedef unsigned long long ull;
const int maxn=1e5+10;
const int inf=0x3f3f3f3f;
struct data
{
int d,v,pw;
}p[maxn];
int cmp(data &a,data &b)
{
return a.d<b.d;
}
int del[maxn],n,l,nxt[maxn],pre[maxn];
struct node
{
int den,num;
node(){}
node(int num,int den)
{
this->num=num;
this->den=den;
}
bool operator<(const node &a)const
{
return (ll)num*a.den<(ll)a.num*den;
}
};
node cal(data a,data b)
{
int V=b.v-a.v;
int D=a.d-b.d;
if(D<0) D+=l;
if(V<0) V=-V,D=l-D;
if(V==0) return node(inf,1);
int GCD=__gcd(V,D);
return node(D/GCD,V/GCD);
}
struct relt
{
int a,b;
node t;
relt(){}
relt(int a,int b,node t)
{
this->a=a;
this->b=b;
this->t=t;
}
bool operator<(const relt &a)const
{
return a.t<t;
}
};
priority_queue<relt>q;
void out(int x)
{
del[x]=1;
nxt[pre[x]]=nxt[x];
pre[nxt[x]]=pre[x];
q.push(relt(pre[x],nxt[x],cal(p[pre[x]],p[nxt[x]])));
}
int main()
{
ios::sync_with_stdio(false);
int T;
cin>>T;
while(T--)
{
cin>>n>>l;
memset(del,0,sizeof(del));
for(int i=0;i<n;i++)
{
cin>>p[i].d;
p[i].pw=i;
}
for(int i=0;i<n;i++)
cin>>p[i].v;
sort(p,p+n,cmp);
while(!q.empty())
q.pop();
for(int i=0;i<n;i++)
{
nxt[i]=(i+1)%n;
pre[i]=(i-1+n)%n;
q.push(relt(i,nxt[i],cal(p[i],p[nxt[i]])));
}
int le=n;
node ans;
while(!q.empty())
{
relt x=q.top();
q.pop();
if(del[x.a] || del[x.b]) continue;
if(--le==1)
{
ans=x.t;
break;
}
if(p[x.a].pw>p[x.b].pw) out(x.b);
else out(x.a);
}
cout<<ans.num<<'/'<<ans.den<<endl;
}
return 0;
}