zoukankan      html  css  js  c++  java
  • 【BZOJ 2402】陶陶的难题II(分数规划+树链剖分+凸包二分)

    传送门

    题解已经写在标题上了

    不过复杂度O(nlog4n)O(nlog^4n)能过也是神了

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=(1<<20)|5;
    inline char gc(){
    	static char ibuf[RLEN],*ib,*ob;
    	(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    	return (ib==ob)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    #define pb push_back
    #define re register
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define cs const
    #define bg begin
    #define ll long long
    template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
    template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
    cs int N=30005;
    char xxx;
    cs double eps=1e-7;
    struct pt{
    	double x,y;
    	pt(double a=0,double b=0):x(a),y(b){}
    	friend inline pt operator -(cs pt &a,cs pt &b){
    		return pt(a.x-b.x,a.y-b.y);
    	}
    	friend inline double operator *(cs pt &a,cs pt &b){
    		return a.x*b.y-a.y*b.x;
    	}
    	friend inline bool operator <(cs pt &a,cs pt &b){
    		return a.x==b.x?a.y<b.y:a.x<b.x;
    	}
    	inline double K(){
    		return y/x;
    	}
    };
    int idx[N];
    double x[N],y[N],p[N],q[N];
    pt qq[N];
    inline vector<pt> gettb(vector<pt> tt){
    	sort(tt.bg(),tt.end());
    	int top=0;qq[top=1]=tt[0];
    	for(int i=1;i<tt.size();i++){
    		while(top>1&&(qq[top]-qq[top-1])*(tt[i]-qq[top-1])>=0)top--;
    		qq[++top]=tt[i];
    	}
    	vector<pt> now;
    	for(int i=1;i<=top;i++)now.pb(qq[i]);
    	return now;
    }
    inline double ask(cs vector<pt> &tt,double k){
    	int l=1,r=tt.size()-1,res=0;
    	while(l<=r){
    		int mid=(l+r)>>1;
    		if((tt[mid]-tt[mid-1]).K()>=k)l=mid+1,res=mid;
    		else r=mid-1;
    	}
    	return tt[res].y-tt[res].x*k;
    }
    struct data{
    	double a,b;
    	data(double _a=0,double _b=0):a(_a),b(_b){}
    	friend inline data operator +(cs data &a,cs data &b){
    		return data(max(a.a,b.a),max(a.b,b.b));
    	}
    };
    namespace Seg{
    	vector<pt> tr[2][N<<2];
    	#define lc (u<<1)
    	#define rc ((u<<1)|1)
    	#define mid ((l+r)>>1)
    	void build(int u,int l,int r){
    		vector<pt>now;
    		for(int i=l;i<=r;i++)now.pb(pt(x[idx[i]],y[idx[i]]));
    		tr[0][u]=gettb(now);now.clear();
    		for(int i=l;i<=r;i++)now.pb(pt(p[idx[i]],q[idx[i]]));
    		tr[1][u]=gettb(now);
    		if(l==r)return;
    		build(lc,l,mid),build(rc,mid+1,r);
    	}
    	data query(int u,int l,int r,int st,int des,double k){
    	//	cerr<<u<<" "<<l<<" "<<r<<" "<<st<<" "<<des<<'
    ';
    		if(st<=l&&r<=des)return data(ask(tr[0][u],k),ask(tr[1][u],k));
    		if(des<=mid)return query(lc,l,mid,st,des,k);
    		if(st>mid)return query(rc,mid+1,r,st,des,k);
    		return query(lc,l,mid,st,des,k)+query(rc,mid+1,r,st,des,k);
    	}
    	#undef lc
    	#undef rc
    	#undef mid
    }
    vector<int> e[N];
    int in[N],dfn,siz[N],son[N],top[N],fa[N],dep[N];
    int n,m;
    double mx;
    void dfs1(int u){
    	siz[u]=1;
    	for(int &v:e[u]){
    		if(v==fa[u])continue;
    		fa[v]=u,dep[v]=dep[u]+1;
    		dfs1(v),siz[u]+=siz[v];
    		if(siz[v]>siz[son[u]])son[u]=v;
    	}
    }
    void dfs2(int u,int tp){
    	top[u]=tp,in[u]=++dfn,idx[dfn]=u;
    	if(son[u])dfs2(son[u],tp);
    	for(int &v:e[u]){
    		if(v==fa[u]||v==son[u])continue;
    		dfs2(v,v);
    	}
    }
    inline double pathquery(int u,int v,double k){
    	data now(-1e9,-1e9);
    	while(top[u]!=top[v]){
    		if(dep[top[u]]<dep[top[v]])swap(u,v);
    		now=now+Seg::query(1,1,n,in[top[u]],in[u],k);
    		u=fa[top[u]];
    	}
    	if(dep[u]<dep[v])swap(u,v);
    	now=now+Seg::query(1,1,n,in[v],in[u],k);
    	return now.a+now.b;
    }
    char yyy;
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++)scanf("%lf",&x[i]);
    	for(int i=1;i<=n;i++)scanf("%lf",&y[i]);
    	for(int i=1;i<=n;i++)scanf("%lf",&p[i]);
    	for(int i=1;i<=n;i++)scanf("%lf",&q[i]);
    	for(int i=1;i<=n;i++)chemx(mx,y[i]/x[i]),chemx(mx,q[i]/p[i]);
    	for(int i=1;i<n;i++){
    		int u=read(),v=read();
    		e[u].pb(v),e[v].pb(u);
    	}
    	dep[1]=1,dfs1(1),dfs2(1,1);
    	Seg::build(1,1,n);
    	m=read();
    	for(int i=1;i<=m;i++){
    		int a=read(),b=read();
    		double l=0,r=mx;
    		while(l+eps<r){
    			double mid=(l+r)*0.5;
    			if(pathquery(a,b,mid)>=0)l=mid;
    			else r=mid;
    		}
    		printf("%.4lf
    ",l);
    	}
    }
    
  • 相关阅读:
    VUE前端项目配置代理解决跨域问题
    面试题:无序数组排序后的最大相邻差
    Vue项目中更改Vux组件中的样式
    iOS13适配 UITableView 种Cell出现带方框的小箭头
    JavaScript 中的require,import,export
    前端框架 Less 学习与实践
    Vue textarea 高度自适应
    Vue项目中添加手势实现左滑右滑操作
    day24 多态--后续
    day24 继承、封装和多态
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328390.html
Copyright © 2011-2022 走看看