Luogu P5416 [CTSC2016] Путешествие во времени (сегмент дерева разделов)

Тема
упрощать смысл вопросов: Вы должны поддерживать \ (\ п) наборы, набор элементов кортежа \ ((х-, v) \) . Коллекция \ (я \) генерируется на основе оригинальной коллекции моды \ (p_i \) в качестве образца, после расширения или удаления элемента , чтобы получить новую коллекцию. Там \ (Q \) раз спросил каждый данный \ (Y \) и задать набор \ (I \) , требования из множества \ (I \) найти элемент, чтобы свести к минимуму \ ((х-у ) ^ 2 + v \) .
Во- первых сплит формула \ ((XY) ^ 2 = Х ^ + V ^ 2 + Y + 2-2xy V \) , так что она равна \ (К \) , т.е. \ (х ^ 2 + у ^ 2-2xy + V к = \) .
Транспонирование у \ (2yx + К = Х ^ У ^ 2 + 2 + V \) , можно рассматривать как \ ((х, х ^ 2 + у ^ 2 + V) \) в точке принятия решения, \ (2Y \) представляет собой наклон, \ (к \) как \ (Y \) оси перехвата. Так что это может быть решено для поддержания выпуклой оболочки.
Мы знаем , что каждый элемент \ (ДФС \)Последовательность будет отображаться в виде части диапазона.
Каждая точка добавляется или удаляется независимо от элементов приведет к новой серии, таким образом, общее количество интервалов \ (О (п) \) есть.
Элемент по \ (Х \) после вставки в порядке возрастания дерева сегмента, каждый узел сохраняет выпуклую оболочку.
Пресс - запрос \ (Y \) в порядке возрастания, но может обеспечить прямой доступ к каждой операции на выпуклой передней стоимости жилья.

#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]);
}

рекомендация

отwww.cnblogs.com/cjoierShiina-Mashiro/p/11519553.html