[CTSC2016] Time Travel (Line Segment Tree + Convex Hull)

It should be more routine, but it is still not easy to A-drop.

Let’s take a look at the ideas below, and if the ideas are clear, it will not be difficult to write them out.

 

0. Obviously y, z coordinates are funny, just ignore it.

1. If x does not change, then set it directly.

2. Considering a space and querying x0, it is found through the formula that it is actually: treating each planet as a linear function is actually asking for the minimum value of all linear functions in this space at x0.

3. This is obviously a convex hull, so we need to maintain a convex hull for each space, and the space is tree-like as a whole. It is conceivable to use DFS order + line segment tree to maintain the interval.

4. Preprocess the existence range of each planet and permanently mark it on the line segment tree. When querying, recursively find the minimum value in turn.

5. Regarding how to store the convex hull on the line segment tree, you can scan it first to reserve space, or you can directly use vector storage like http://www.cnblogs.com/HocRiser/p/8549456.html , the latter may Slow down, open the read-in plug-in and it's over.

 1 #include<cstdio>
 2 #include<vector>
 3 #include<algorithm>
 4 #define ls (x<<1)
 5 #define rs (ls|1)
 6 #define lson ls,L,mid
 7 #define rson rs,mid+1,R
 8 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 9 typedef long long ll;
10 using namespace std;
11 
12 const int N=500010;
13 const ll inf=1000000000000000000ll;
14 int n,m,cnt,x,y,c,tim,op,fr,d,id[N],L[N],R[N],X[N],K[N];
15 int h[N],nxt[N],pos[N],to[N],st[N<<2],ed[N<<2],q[N];
16 ll a[N],b[N],ans[N];
17 vector<int>T[N<<2],V[N];
18 
19 ll rd(){
20     ll x=0; bool t=0; char ch=getchar();
21     while (ch<'0' || ch>'9') t|=(ch=='-'),ch=getchar();
22     while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
23     if (t) return -x; else return x;
24 }
25 
26 bool cmp0(int x,int y){ return L[x]<L[y]; }
27 bool cmp1(int x,int y){ return a[x]>a[y] || (a[x]==a[y] && b[x]>b[y]); }  
28 bool cmp2(int a,int b){ return X[a]<X[b]; }
29 bool Cmp(int x,int y,int z){ return ((b[y]-b[x])*(a[y]-a[z])>=(b[z]-b[y])*(a[x]-a[y])); }
30 
31 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
32 
33 void dfs(int x){ L[x]=++tim; for (int i=h[x]; i; i=nxt[i]) dfs(to[i]); R[x]=tim; }
34 
35 void build(int x,int L,int R){
36     ed[x]=-1;
37     if (L==R) { pos[L]=x; return; }
38     int mid=(L+R)>>1; build(lson); build(rson);
39 }
40 
41 void ins(int x,int L,int R,int l,int r,int k){
42     if (L==l && r==R){
43         int &j=ed[x];
44         for (; st[x]<j && Cmp(T[x][j-1],T[x][j],k); j--,T[x].pop_back());
45         j++; T[x].push_back(k);
46         return;
47     }
48     int mid=(L+R)>>1;
49     if (r<=mid) ins(lson,l,r,k);
50     else if (l>mid) ins(rson,l,r,k);
51         else ins(lson,l,mid,k),ins(rson,mid+1,r,k);
52 }
53 
54 ll que(int k,int x){
55     ll ans=inf;
56     for (int i=pos[k]; i; i>>=1){
57         int &j=st[i];
58         for (; j<ed[i] && (a[T[i][j]]-a[T[i][j+1]])*x>=b[T[i][j+1]]-b[T[i][j]]; j++);
59         if (j<=ed[i]) ans=min(ans,a[T[i][j]]*x+b[T[i][j]]);
60     }
61     return ans;
62 }
63 
64 int main(){
65     freopen("travel.in","r",stdin);
66     freopen("travel.out","w",stdout);
67     n=rd(); m=rd(); b[1]=rd(); id[1]=1;
68     rep(i,2,n){
69         op=rd(); fr=rd()+1; d=rd()+1; add(fr,i);
70         if (op) V[d].push_back(i);
71         else id[d]=i,x=rd(),rd(),rd(),c=rd(),a[d]=-2ll*x,b[d]=1ll*x*x+c;
72     }
73     dfs(1); build(1,1,n);
74     rep(i,1,n) q[i]=i; sort(q+1,q+n+1,cmp1);
75     rep(l,1,n) if (id[q[l]]){
76         int i=q[l];
77         sort(V[i].begin(),V[i].end(),cmp0); int k=L[id[i]];
78         for (vector<int>::iterator it=V[i].begin(); it!=V[i].end(); k=R[*it]+1,it++)
79             if (k<L[*it]) ins(1,1,n,k,L[*it]-1,i);
80         if (k<=R[id[i]]) ins(1,1,n,k,R[id[i]],i);
81     }
82     rep(i,1,m) q[i]=i,x=rd(),y=rd(),K[i]=L[x+1],X[i]=y;
83     sort(q+1,q+m+1,cmp2);
84     rep(i,1,m) ans[q[i]]=que(K[q[i]],X[q[i]])+1ll*X[q[i]]*X[q[i]];
85     rep(i,1,m) printf("%lld\n",ans[i]);
86     return 0;
87 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325381974&siteId=291194637