Topic: Given a tree, each point has two coordinates (X1,Y1) and (X2,y2), several times asked a chain on the selection of two points I and J (can be the same), (Y1I+Y2J)/(X1I+X2J) the maximum value
I didn't see it as a 01-score plan ... It's so old ...
Two-point answer ans, the problem turns into validation (Y1I+Y2J)/(X1I+X2J) whether >=ans
The formula can be deformed (y1i-ans*x1i) + (Y2J-ANS*X2J) >=0
The plus side is independent and can be calculated separately
The problem turns to the y-ans*x biggest point on the chain
Make P=y-ans*x the Y=ans*x+p
We found that this is a form of slope optimization so we can use tree chain to maintain convex hull with segment tree.
Each query tree is chained to a log segment tree one log each time the convex packet is divided by a log plus the outermost two total 4 log
It's a miracle to be able to live ....
#include <cmath> #include <vector> #include <cstdio> #include <cstring> #include <iostream > #include <algorithm> #define M 30300#define EPS 1e-7#define INF 1e10using namespace std;struct point{double x, y; Point () {}point (double _,double __): X (_), Y (__) {}friend-point operator + (const-point-&p1,const-point &p2) {return Point (P1.X+P2.X,P1.Y+P2.Y);} Friend point operator-(const point &p1,const point &p2) {return point (P1.X-P2.X,P1.Y-P2.Y);} Friend double operator * (const point &p1,const point &p2) {return p1.x*p2.y-p1.y*p2.x;} friend BOOL operator < (const point &p1,const point &p2) {return p1.x<p2.x | | p1.x==p2.x&&p1.y<p2 . Y;} Friend Double Get_slope (const point &p1,const point &p2) {if (Fabs (p1.x-p2.x) <eps) return p1.y<p2.y? Inf:-inf;return (P1.Y-P2.Y)/(p1.x-p2.x);}} Points1[m],points2[m];struct abcd{int To,next;} Table[m<<1];int head[m],tot;int n,m;int fa[m],son[m],dpt[m],size[m];int top[m],pos[m],A[m],cnt;void Add (int x,int y) {table[++tot].to=y;table[tot].next=head[x];head[x]=tot;} void DFS1 (int x) {int i;dpt[x]=dpt[fa[x]]+1;size[x]=1;for (i=head[x];i;i=table[i].next) {if (table[i].to==fa[x]) CONTINUE;FA[TABLE[I].TO]=X;DFS1 (table[i].to); Size[x]+=size[table[i].to];if (Size[table[i].to]>size[son[x]) son[x]=table[i].to;}} void DFS2 (int x) {int i;a[pos[x]=++cnt]=x;if (son[fa[x]]==x) top[x]=top[fa[x]];elsetop[x]=x;if (Son[x]) DFS2 (son[x]); for (I=head[x];i;i=table[i].next) {if (table[i].to==fa[x]| | TABLE[I].TO==SON[X]) CONTINUE;DFS2 (table[i].to);}} void Merge (const vector<point> &h1,const vector<point> &h2,vector<Point> &h) {vector <point>::const_iterator I,j;i=h1.begin (); J=h2.begin (); int top=0;while (i!=h1.end () | | j!=h2.end ()) {Point p=i== H1.end ()? *j++:j==h2.end () *i++:* i<*j?*i++:* j++;while (top>=2 && (H[top-1]-h[top-2]) * (P-h[top-1]) >-eps) H.pop_back (), Top--;h.push_back (p), top++;}} Double bisection (const vector<point> &h,double k) {int l=0,r=h.size (); while (l+1<r) {int mid=l+r>>1;if (Get_slope (H[mid-1],h[mid]) >k-eps) L=mid;elser=mid;} return h[l].y-k*h[l].x;} struct Segtree{segtree *ls,*rs;vector<point> h1,h2;void* operator new (size_t) {static Segtree mempool[m<<1 ],*c=mempool;return C + +;} void Build_tree (int x,int y) {int mid=x+y>>1;if (x==y) {h1.push_back (Points1[a[mid]]); H2.push_back (points2[a[ Mid]]); return;} (Ls=new segtree)->build_tree (x,mid);(rs=new segtree)->build_tree (mid+1,y); Merge (LS->H1,RS->H1,H1); Merge (LS->H2,RS->H2,H2);} Double Query (int x,int y,int l,int r,double k,bool flag) {int mid=x+y>>1;if (X==L&&Y==R) return!flag? Bisection (h1,k): bisection (H2,k), if (R<=mid) return Ls->query (X,mid,l,r,k,flag), if (L>mid) return rs-> Query (Mid+1,y,l,r,k,flag); return Max (Ls->query (X,mid,l,mid,k,flag), Rs->query (Mid+1,y,mid+1,r,k,flag));}} *tree=new Segtree[m];d ouble Query (int x,int y,double k,bool flag) {int fx=top[x],fy=top[y];d ouble re=-inf;while (fx!=fy) {iF (Dpt[fx]<dpt[fy]) swap (x, y), swap (Fx,fy), Re=max (Re,tree->query (1,n,pos[fx],pos[x],k,flag)); x=fa[fx];fx= TOP[X];} if (Dpt[x]<dpt[y]) swap (x, y); Re=max (Re,tree->query (1,n,pos[y],pos[x],k,flag)); return re;} Double bisection (int x,int y) {double l=0,r=1e8;while (r-l>1e-5) {double mid= (l+r)/2.0;if (Query (x,y,mid,false) + Query (X,y,mid,true) > 0) L=mid;elser=mid;} Return (L+R)/2;} int main () {int i,x,y;cin>>n;for (i=1;i<=n;i++) scanf ("%lf", &points1[i].x), for (i=1;i<=n;i++) scanf (" %lf ", &points1[i].y), for (i=1;i<=n;i++) scanf ("%lf ", &points2[i].x), and for (i=1;i<=n;i++) scanf ("%lf ", &POINTS2[I].Y); for (i=1;i<n;i++) {scanf ("%d%d", &x,&y); ADD (x, y); ADD (y,x);} DFS1 (1);D FS2 (1), Tree->build_tree (1,n), Cin>>m;for (i=1;i<=m;i++) {scanf ("%d%d", &x,&y);p rintf ( "%.5lf\n", bisection (x, y));}}
Bzoj 2402 Tata Puzzle II Two-part answer + slope optimization + Tree chain split + segment tree Maintenance convex hull