[XSY2541] gunboat official contest of the season (heap)

Face questions

Description

Gunboat Competition is a dangerous game. In order to win this game, contestants may sacrifice their lives.

Participants will be a length \ (L \) circular track on the game. At the start of the game ( \ (0 \) time), all participants standing positions on different tracks, the first of which \ (I \) contestants standing position \ (di (0≤di <L) \) on . Then start the race. Each participant drove its gunboats, speed \ (vi \) (speed can be positive or negative, can also \ (0 \) . Entrants moving speed is positive clockwise speed is negative representation participants move counter-clockwise). Each participant's speed is different.

The first \ (i \) contestants have (i \) \ -point energy value. During the race, participants are likely to encounter (meet here refers to the contestants falls exactly in the same place at the same time). Each two contestants \ (i, j \) when met, low energy value Participants were shot out.

When just one person on the field, ending the game.

When asked end of the game.

Input

The first line contains two positive integers \ (n, L (1≤n≤10 ^ 5,1≤L≤10 ^ 9) \)

The next line contains the \ (n-\) different integers \ (di (0≤di <L) \)

The next line contains \ (n \) different integers \ (vi (| vi | ≤10 ^ 9) \)

Output

Outputting a fractional \ (X / Y \) represents the end time, where \ (GCD (X-, the Y) =. 1 \) . If the answer is \ (0 \) , should only be output " \ (0 \) " (without the quotes).

Sample Input & Sample Output

Sample input [1]

2 4
0 2
3 2

Sample output [1]

2/1

Sample input [2]

10 100
56 89 62 71 7 24 83 1 47 52
9 -16 34 -38 47 49 -32 17 39 -9

Sample output [2]

37/7

The

For \ (20 \% \) data, \ (^ 3,1≤L≤10 1≤n≤10 ^ 4, | vi | ≤10 ^ 4 \)

For \ (40 \% \) data, \ (^ 4,1≤L≤10 1≤n≤10 ^ 5, | vi | ≤10 ^ 5 \)

For all the data, \ (^ 5,1≤L≤10 1≤n≤10 ^ 9, | vi | 9,0≤wi≤n ≤10 ^ \)

answer

The first solution is relatively straightforward, we eliminated the order of \ (n-1 \) individuals out one by one. There is a relatively easy to prove conclusion: Suppose now on the left ring \ (k \) individuals, then the next elimination occurred for the first time must be adjacent to the ring on two people collide. This notice is eliminated if the individual does not have any influence on the subsequent process, if we can find out who this time were eliminated, this man is directly removed from the current state, you will be able to become a problem only \ ( k-1 \) the individual sub-problems, we have to solve this problem child the same way.

So we can use a heap to maintain the current all neighboring people (adjacent distance sense) met on the ring time, removed from the minimum, you will find the first person to be eliminated, after the man removed, not the original phase two people on the adjacent neighborhood, and determined at the same time they met, join the heap, repeat the process until you find the last person to be eliminated so far.

Maintenance time two people meet directly Points \ (O (1) \) maintenance. At the beginning of the \ (n \) individuals in the neighboring people encounter time insert stack, each insert is \ (O (log (the n-)) \) , so this time complexity is \ (O (nlog ( the n-)) \) . After the total to delete \ (n \) personal, each time you want to delete Shihai element into a heap needs \ (O (log (n) ) \) , so this is a period of time is \ (O (log (n) ) \) .

So the total time complexity is \ (O (nlog (n-)) \) .

The complete code is as follows:

#include<bits/stdc++.h>
 
#define N 100010
 
using namespace std;
 
struct Time
{
    int a,b;
    double t;
    bool operator < (const Time &a) const
    {
        return a.t<t;//按相遇时间排序
    }
}ans;
 
struct data
{
    int d,v,id;
}a[N];
 
int n,L,l[N],r[N];
bool flag[N];
 
priority_queue<Time>q;//小根堆
 
bool cmp(data a,data b)//按距离排序
{
    return a.d<b.d;
}
 
double intersection(data a,data b,int x)//O1求相遇时间
{
    if(a.d>b.d)
    {
        if(a.v>b.v)
        {
            if(!x)return (double)(L-(a.d-b.d))/(double)(a.v-b.v);
            if(x==1)return (double)L-(a.d-b.d);
            return (double)a.v-b.v;
        }
        else
        {
            if(!x)return (double)(a.d-b.d)/(double)(b.v-a.v);
            if(x==1)return (double)a.d-b.d;
            return (double)b.v-a.v;
        }
    }
    else
    {
        if(a.v>b.v)
        {
            if(!x)return (double)(b.d-a.d)/(double)(a.v-b.v);
            if(x==1)return (double)b.d-a.d;
            return (double)a.v-b.v;
        }
        else
        {
            if(!x)return (double)(L-(b.d-a.d))/(double)(b.v-a.v);
            if(x==1)return (double)L-(b.d-a.d);
            return (double)b.v-a.v;
        }
    }
}
 
int gcd(int a,int b)
{
    if(!b)return a;
    return gcd(b,a%b);
}
 
int main()
{
    scanf("%d%d",&n,&L);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i].d);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i].v);
    for(int i=1;i<=n;i++)
        a[i].id=i;
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        l[i]=(i==1?n:i-1);//l[i]为当前环上i左边相邻的点的编号
        r[i]=(i==n?1:i+1);//r[i]同理
        q.push((Time){l[i],i,intersection(a[l[i]],a[i],0)});//将相邻两人的相遇时间放进队列
    }
    while(!q.empty())
    {
        Time now=q.top();
        q.pop();
        if(flag[now.a]||flag[now.b])continue;
        ans=now;
        if(a[now.a].id<a[now.b].id)
        {
            flag[now.a]=true;
            l[now.b]=l[now.a];
            r[l[now.b]]=now.b;
            if(l[now.b]!=now.b)q.push((Time){l[now.b],now.b,intersection(a[l[now.b]],a[now.b],0)});
        }
        else
        {
            flag[now.b]=true;
            r[now.a]=r[now.b];
            l[r[now.a]]=now.a;
            if(r[now.a]!=now.a)q.push((Time){now.a,r[now.a],intersection(a[now.a],a[r[now.a]],0)});
        }
    }
    int x=(int)intersection(a[ans.a],a[ans.b],1);
    int y=(int)intersection(a[ans.a],a[ans.b],2);
    int g=gcd(x,y);
    printf("%d/%d\n",x/g,y/g);
    return 0;
}

Guess you like

Origin www.cnblogs.com/ez-lcw/p/11348642.html