Luogu P5416 [CTSC2016] Time Travel (segment tree partition)

Topic
simplify meaning of the questions: Do you need to maintain \ (\ n) sets, a collection of elements tuple \ ((the X-, v) \) . Collection \ (i \) is generated based on an original fashion collection \ (p_i \) as a sample, after expansion or delete an element to obtain new collection. There \ (Q \) times asked every given \ (Y \) and specify a set of \ (I \) , the requirements from the set \ (I \) find an element, to minimize \ ((x-y ) ^ 2 + v \) .
First split formula \ ((XY) ^ 2 = X ^ + V ^ 2 + Y + 2-2xy V \) , so that it is equal to \ (K \) i.e. \ (x ^ 2 + y ^ 2-2xy + v k = \) .
Transposition have \ (2yx + K = X ^ Y ^ 2 + 2 + V \) , can be viewed as \ ((x, x ^ 2 + y ^ 2 + v) \) of the decision point, \ (2Y \) is the slope, \ (K \) to as \ (Y \) axis intercept. So this can be resolved to maintain the convex hull.
We know that every element in \ (dfs \)Sequence will appear in the form of a section of the range.
Each point is added or deleted regardless of the elements will result in a new range, so the total number of intervals is \ (O (n) \) is.
The element according to \ (X \) after insertion in ascending order segment tree, each node maintains a convex hull.
Press inquiry \ (Y \) in ascending order, but may enable direct access to each operation on a convex front housing value.

#include<bits/stdc++.h>
#define LL long long
#define db double
#define pb push_back
#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)
#define INF 1e18
using namespace std;
const int N=500007;
int L[N<<2],R[N<<2],t[N],dfn[N],T[N],n,m,Time;
LL C[N],ans[N],val[N];
vector<int>G[N],al[N],ar[N],w[N<<2];
struct node{LL x,val,id;}a[N];
int cmp(int a,int b){return val[a]<val[b];}
int operator<(node a,node b){return a.val<b.val;}
LL min(LL a,LL b){return a<b? a:b;}
db K(int x ,int y){return (val[x]*val[x]+C[x]-val[y]*val[y]-C[y])/(db)(val[x]-val[y]);}
void dfs(int u,int fa)
{
    dfn[u]=++Time;
    if(T[u]>0) al[T[u]].pb(Time);
    if(T[u]<0) ar[-T[u]].pb(Time-1);
    for(int i=G[u].size()-1,v;~i;--i) if((v=G[u][i])^fa) dfs(v,u);
    if(T[u]>0) ar[T[u]].pb(Time);
    if(T[u]<0) al[-T[u]].pb(Time+1);
}
void build(int p,int l,int r)
{
    L[p]=0,R[p]=-1;
    if(l==r) return ;
    build(ls,l,mid),build(rs,mid+1,r);
}
void update(int p,int l,int r,int ql,int qr,int P)
{
    if(ql==l&&r==qr)
    {
    while(w[p].size()<=R[p]+5) w[p].pb(0);
    if(L[p]<=R[p]&&val[w[p][R[p]]]==val[P])
    {
        if(C[w[p][R[p]]]<=C[P]) return ;
        --R[p];
    }
    while(L[p]<R[p]&&K(w[p][R[p]],P)<K(w[p][R[p]],w[p][R[p]-1])) --R[p];
    w[p][++R[p]]=P;
    return ;
    }
    if(qr<=mid) update(ls,l,mid,ql,qr,P);
    else if(ql>mid) update(rs,mid+1,r,ql,qr,P);
    else update(ls,l,mid,ql,mid,P),update(rs,mid+1,r,mid+1,qr,P);
}
LL query(int p,int l,int r,int x,LL t,LL sum)
{
    LL ans=INF;
    while(L[p]<R[p]&&K(w[p][L[p]],w[p][L[p]+1])<=2.0*t) ++L[p];
    if(L[p]<=R[p]&&w[p].size()>0) ans=(t-val[w[p][L[p]]])*(t-val[w[p][L[p]]])+C[w[p][L[p]]];
    ans=min(ans,sum);
    if(l==r) return ans;
    return x<=mid? query(ls,l,mid,x,t,ans):query(rs,mid+1,r,x,t,ans);
}
int main()
{
    int i,j,k,u,x,opt,l,r;
    scanf("%d%d%lld",&n,&m,&C[0]);
    for(i=1;i<n;++i) scanf("%d%d%d",&opt,&u,&x),G[u].pb(i),(opt? (T[i]=-x):(T[i]=x,scanf("%lld%d%d%lld",&val[x],&u,&u,&C[x])));
    dfs(0,0),build(1,1,n);
    for(i=1;i<=n;++i) t[i]=i;
    sort(t+1,t+n+1,cmp),update(1,1,n,1,n,0);
    for(i=1;i<=n;++i) for(k=t[i],j=0;j<al[k].size();++j) if((l=al[k][j])<=(r=ar[k][j])) update(1,1,n,l,r,k);
    for(i=1;i<=m;++i) scanf("%lld%lld",&a[i].x,&a[i].val),a[i].id=i;
    sort(a+1,a+m+1);
    for(i=1;i<=m;++i) ans[a[i].id]=query(1,1,n,dfn[a[i].x],a[i].val,INF);
    for(i=1;i<=m;++i) printf("%lld\n",ans[i]);
}

Guess you like

Origin www.cnblogs.com/cjoierShiina-Mashiro/p/11519553.html