CF704E Iron Man

CF704E Iron Man

Through unremitting (copy solution to a problem) after work, and finally AC this problem.

 

That is simple.

Consider the case of a chain,

Establish a Cartesian coordinate system.

The abscissa is t, the ordinate is a distance d from the beginning of the chain

m is a segment paths

So it could crash, if and only if there is cross the line.

 

To a collection of line segments, find a point of intersection between the first two by two.

practice:

Scan lines.

set maintenance segment, increment to the ordinate, the ordinate slope by the same increment. Overload global variable number less than X.

Add a line when it and its predecessor successor intersection.

To delete a line when it's successor and its predecessor intersection.

The intersection of the horizontal axis contribute to the answer.

 

While the former can not be determined how large the intersection of two lines or even the relative position will change after the intersection

But it does not matter! Prior to the first intersection occurs in pairs of the same order line

We only need the first intersection. If following the operation is greater than the abscissa ans, directly BREAK!

The above requirements must be obtained first intersection point of intersection (FIG own painting)

 

The tree? Split Tree chain, directly into the straight up and down the chain to do it! ! ! !

Using Tree logn cross section, classic routines

 

Method to realize:

1. Note the heavy chain head side unto himself.

2. The line of storage:

If written directly in the form of k * x + b, b will be great, resulting in accuracy error. And when the little intersect too much trouble.

So the use of a physical embodiment

Record time to reach this chain of start time, start position, end position, speed

Meet demand intersection is the problem.

Seeking a position of abscissa is the X value, is used: a displacement velocity * time =

eps apart is 1e-9

 

O (nlog ^ 2n) very unhappy.

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
    char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=998244353;
il int ad(int x,int y){return x+y>=mod?x+y-mod:x+y;}
the you intended ( you get, you y) { return ad (x, mod- y)}
il int mul(int x,int y){return (ll)x*y%mod;}
il void inc(int &x,int y){x=ad(x,y);}
il void inc2(int &x,int y){x=mul(x,y);}
il int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}
template<class ...Args>il int ad(const int a,const int b,const Args &...args) {return ad(ad(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
}
namespace Miracle{
const int N=1e5+5;
const double inf=1e13;
const double eps=1e-9;
int n,m;
struct node{
    int nxt,to;
}eg[2*N];
int hd[N],cnt;
void add(int x,int y){
    eg[++cnt].nxt=hd[x];
    eg[cnt].to=y;
    hd[x]=cnt;
}
int dfn[N],df,top[N],fa[N],id[N];
int son[N],sz[N],dep[N];

/////////////////////////
double X;//here is X!
/////////////////////////

int Fabs(double x){
    if(x>eps) return 1;
    if(x<-eps) return -1;
    return 0;
}
struct line{
    int st,nd;
    double bt,v;
    double friend operator &(line x,line y){
        if(Fabs(x.v-y.v)){
            double ny=y.st+(x.bt-y.bt)*y.v;
            double tim=x.bt+(ny-x.st)/(x.v-y.v);
            if(tim>y.bt-eps&&tim>x.bt-eps&&tim<y.bt+(y.nd-y.st)/y.v+eps&&tim<x.bt+(x.nd-x.st)/x.v+eps) return tim;
            return inf;
        } Else {
             if (Fabs ((y.st-x.st) /x.v+x.bt-y.bt) == 0 ) return max (y.bt, x.bt);
            return INF;
        }
    }
    bool friend operator <(line x,line y){
        double nx=x.st+(X-x.bt)*x.v,ny=y.st+(X-y.bt)*y.v;
        if(Fabs(nx-ny)!=0) return nx<ny;
        if(Fabs(x.v-y.v)!=0)  return x.v<y.v;
        if(x.st!=y.st) return x.st<y.st;
        return x.nd<y.nd;
    }
};

struct hl{
    vector<line>mem;
    int st,nd;
}h[N];
int everything;

void dfs(int x){
    No. [x] = 1 ;
    dep[x]=dep[fa[x]]+1;
    for(reg i=hd[x];i;i=eg[i].nxt){
        int y=eg[i].to;
        if(y==fa[x]) continue;
        fa[y]=x;
        dfs(y);
        sz[x]+=sz[y];
        if(sz[y]>sz[son[x]]) son[x]=y;
    }
}
void dfs2(int x){
    dfn[x]=++df;
    if(!top[x]){
        ++tot;
        if(x==1) h[tot].st=x;
        else h[tot].st=fa[x];
        
        top[x]=x;
        id[x]=tot;
        h [tot] .nd = x;
    }else{
        id[x]=id[top[x]];
        h[id[x]].nd=x;
    }
    if(son[x]) top[son[x]]=top[x],dfs2(son[x]);
    for(reg i=hd[x];i;i=eg[i].nxt){
        int y=eg[i].to;
        if(y==fa[x]) continue;
        if(y==son[x]) continue;
        DFS2 (y);
    }
}
int lca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        x=fa[top[x]]; 
    }
    if(dep[x]<dep[y]) swap(x,y);
    return y;
}
void push(int x,int y,int t,int c){
    double xt=t;
    int anc=lca(x,y);
    int dis=dep[x]+dep[y]-2*dep[anc];
    double yt=(double)t+(double)dis/c;
    while(top[x]!=top[y]){
        if(dep[top[x]]>dep[top[y]]){//jump x
            int now=id[x];
            line lp;
            lp.bt=xt;
            lp.st=dep[x]-dep[h[now].st];
            lp.nd=0;lp.v=-c;h[now].mem.pb(lp);
            xt+=(double)(dep[x]-dep[h[now].st])/c;
            x=fa[top[x]];
        }else{//jump y
            int now=id[y];
            line lp;
            yt-=(double)(dep[y]-dep[h[now].st])/c;
            lp.bt=yt;
            lp.st=0;lp.nd=dep[y]-dep[h[now].st];
            lp.v=c;
            h[now].mem.pb(lp);
            y = F [top [y]];
        }
    }
    if(dep[x]>dep[y]){
        int now=id[x];
        line lp;
        lp.bt=xt;
        lp.st=dep[x]-dep[h[now].st];
        lp.nd=dep[y]-dep[h[now].st];lp.v=-c;h[now].mem.pb(lp);
    }else{
           int now=id[y];
        line lp;
        yt-=(double)(dep[y]-dep[x])/c;
        lp.bt=yt;
        lp.st=dep[x]-dep[h[now].st];lp.nd=dep[y]-dep[h[now].st];
        lp.v=c;
        h[now].mem.pb(lp);
    }
}

dual years = inf;

struct ev{    
    double p;
    int id,tp;
    bool friend operator <(ev a,ev b){
        if(Fabs(a.p-b.p)!=0) return a.p<b.p;
        return a.tp>b.tp;
    }
} and [ 2 * N];
multiset<line>s;

int main () {
    rd (n); rd (m);
    int x,y;
    for(reg i=1;i<n;++i){
        rd (x) rd (y);
        add(x,y);
        add(y,x);
    }
    dfs(1);
    dfs2(1);
    
    int t,c;
    for(reg i=1;i<=m;++i){
        rd (t); rd (c); rd (x); rd (y);
        push(x,y,t,c);
    }
    
    ans=inf;
    for(reg i=1;i<=tot;++i){
        int num=0;
        for(reg o=0;o<(int)h[i].mem.size();++o){
            line lp=h[i].mem[o];
            E [ ++ whether] hu = O;
            out [whether] .p = lp.bt;
            out [whether] .tp = 1 ;
            
            E [ ++ whether] hu = O;
            e[num].p=lp.bt+(lp.nd-lp.st)/lp.v;
            out [whether] .tp = - 1 ;
        }
        sort (e + 1 , a + e + 1 );
        s.clear();
        
        for(reg j=1;j<=num;++j){
            X=e[j].p;
            if(X>ans-eps) break;
            line lp=h[i].mem[e[j].id];
            if(e[j].tp==1){
                s.insert(lp);
                auto bc=s.lower_bound(lp);
                auto tmp=bc;++tmp;
                if(tmp!=s.end()){
                    ans=min(ans,(*tmp)&lp);
                }
                tmp=bc;
                if(tmp!=s.begin()){
                    --tmp;
                    ans=min(ans,(*tmp)&lp);
                }
            }else{
                auto bc=s.lower_bound(lp);
                if(bc!=s.end()){
                    if(bc!=s.begin()){
                        Auto Q = Bc; - Q;
                        years = min (years (* bc) & (* pr));
                    }
                }
                auto now=s.find(lp);
                s.erase(now);
            }
        }
    }
    if(ans>=inf-1) puts("-1");
    else printf("%.10lf",ans);
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
*/

Two knowledge points:

1. The minimum required set of intersection of the line segment.

2. chain split tree, the path onto the chain by sequential problem.

 

Guess you like

Origin www.cnblogs.com/Miracevin/p/11079279.html