• BZOJ 2402 陶陶的难题II (01分数规划+树剖+线段树+凸包+二分)


    题目大意:略

    一定范围内求最大值,考虑二分答案

    设现在选择的答案是$mid$,$max left { frac{yi+qj}{xi+pj} ight } geq mid $

    展开可得,$(yi-mid*xi)+(qj-mid*pj)>=0$,只要存在$i,j$使得这个式子成立,说明$mid$能作为答案

    题目并没有要求我们不能选择同一个节点,所以$i,j$之间没有任何关联

    现在需要求出$max left { yi-mid*xi ight }$,$q,p$和$x,y$同理

    移项,$yi=mid*xi+b$,求$b$的最大值,发现这是一个一次函数的形式

    线段树维护树链剖分序,线段树上每个节点都挂一个上凸包,每次用一条斜率为$mid$的直线去切这个凸包即可

    总时间$O(nlog^{4}n)$,理论上过不去,但#巨佬说跑不满

      1 #include <cmath>
      2 #include <vector>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #define N1 30010
      7 #define S1 (N1<<1)
      8 #define T1 (N1<<2)
      9 #define ll long long
     10 #define uint unsigned int
     11 #define rint register int 
     12 #define dd double
     13 #define il inline 
     14 #define inf 233333333
     15 using namespace std;
     16 
     17 const dd eps=0.000001;
     18 int gint()
     19 {
     20     int ret=0,fh=1;char c=getchar();
     21     while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();}
     22     while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
     23     return ret*fh;
     24 }
     25 int n,m;
     26 struct Edge{
     27 int to[S1],nxt[S1],head[N1],cte;
     28 void ae(int u,int v)
     29 {cte++,to[cte]=v,nxt[cte]=head[u],head[u]=cte;}
     30 }E;
     31 struct node{int id;dd val;}tmp[N1];
     32 int cmp1(node s1,node s2){return s1.val<s2.val;}
     33 int stk[N1];
     34 struct SEG{
     35 vector<int>cvh[T1];
     36 void build(int l,int r,int rt,int *A,dd *X,dd *Y)
     37 {
     38     int i,j,cnt=0,tp=0,mid;
     39     for(i=l;i<=r;i++) cnt++,tmp[cnt].id=A[i],tmp[cnt].val=X[A[i]];
     40     sort(tmp+1,tmp+cnt+1,cmp1);
     41     stk[++tp]=tmp[1].id;
     42     for(i=2;i<=cnt;i++)
     43     {
     44         j=tmp[i].id;
     45         while(tp>1&&(Y[j]-Y[stk[tp-1]])*(X[stk[tp]]-X[stk[tp-1]])>=(Y[stk[tp]]-Y[stk[tp-1]])*(X[j]-X[stk[tp-1]])) tp--;
     46         stk[++tp]=j;
     47     }
     48     for(i=1;i<=tp;i++) cvh[rt].push_back(stk[i]);
     49     if(l==r) return;
     50     mid=(l+r)>>1;
     51     build(l,mid,rt<<1,A,X,Y);
     52     build(mid+1,r,rt<<1|1,A,X,Y);
     53 }
     54 dd cvh_query(int rt,dd K,dd *X,dd *Y)
     55 {
     56     if(cvh[rt].size()==1) return Y[cvh[rt][0]]-X[cvh[rt][0]]*K;
     57     int i,l=1,r=cvh[rt].size()-1,mid,p=0,a,b;
     58     a=cvh[rt][0],b=cvh[rt][1];
     59     if((Y[b]-Y[a])<=K*(X[b]-X[a])) return Y[a]-X[a]*K;
     60     while(l<=r){
     61         mid=(l+r)>>1,a=cvh[rt][mid-1],b=cvh[rt][mid];
     62         if((Y[b]-Y[a])>=K*(X[b]-X[a])) p=mid,l=mid+1;
     63         else r=mid-1;
     64     }return Y[cvh[rt][p]]-X[cvh[rt][p]]*K;
     65 }
     66 dd query(int L,int R,int l,int r,int rt,dd K,dd *X,dd *Y)
     67 {
     68     if(L<=l&&r<=R) 
     69         return cvh_query(rt,K,X,Y);
     70     int mid=(l+r)>>1; dd ans=-inf;
     71     if(L<=mid) ans=max(ans,query(L,R,l,mid,rt<<1,K,X,Y));
     72     if(R>mid) ans=max(ans,query(L,R,mid+1,r,rt<<1|1,K,X,Y));
     73     return ans;
     74 }
     75 }xy,pq;
     76 dd X[N1],Y[N1],P[N1],Q[N1];
     77 namespace cut{
     78 int fa[N1],dep[N1],sz[N1],son[N1],tp[N1];
     79 int st[N1],id[N1],tot;
     80 void dfs1(int u,int ff)
     81 {
     82     for(int j=E.head[u];j;j=E.nxt[j])
     83     {
     84         int v=E.to[j];
     85         if(v==ff) continue;
     86         dep[v]=dep[u]+1; fa[v]=u; dfs1(v,u); 
     87         sz[u]+=sz[v]; son[u]=sz[v]>sz[son[u]]?v:son[u]; 
     88     }
     89     sz[u]++;
     90 }
     91 void dfs2(int u)
     92 {
     93     st[u]=++tot,id[tot]=u;
     94     if(son[u]) tp[son[u]]=tp[u], dfs2(son[u]);
     95     for(int j=E.head[u];j;j=E.nxt[j])
     96     {
     97         int v=E.to[j];
     98         if(v==fa[u]||v==son[u]) continue;
     99         tp[v]=v; dfs2(v);
    100     }
    101 }
    102 dd query(int x,int y,dd K)
    103 {
    104     dd mxy=-inf,mpq=-inf;
    105     while(tp[x]!=tp[y])
    106     {
    107         if(dep[tp[x]]<dep[tp[y]]) swap(x,y);
    108         mxy=max(mxy,xy.query(st[tp[x]],st[x],1,n,1,K,X,Y));
    109         mpq=max(mpq,pq.query(st[tp[x]],st[x],1,n,1,K,P,Q));
    110         x=fa[tp[x]];
    111     }
    112     if(dep[x]>dep[y]) swap(x,y);
    113     mxy=max(mxy,xy.query(st[x],st[y],1,n,1,K,X,Y));
    114     mpq=max(mpq,pq.query(st[x],st[y],1,n,1,K,P,Q));
    115     return mxy+mpq;
    116 }
    117 void init()
    118 {
    119     dep[1]=1,dfs1(1,-1);
    120     tp[1]=1,dfs2(1);
    121     xy.build(1,n,1,id,X,Y);
    122     pq.build(1,n,1,id,P,Q);
    123 }
    124 };
    125 
    126 int main()
    127 {
    128     scanf("%d",&n);
    129     int i,x,y;
    130     for(i=1;i<=n;i++) scanf("%lf",&X[i]);
    131     for(i=1;i<=n;i++) scanf("%lf",&Y[i]);
    132     for(i=1;i<=n;i++) scanf("%lf",&P[i]);
    133     for(i=1;i<=n;i++) scanf("%lf",&Q[i]);
    134     for(i=1;i<n;i++) x=gint(),y=gint(),E.ae(x,y),E.ae(y,x);
    135     cut::init();
    136     scanf("%d",&m);
    137     dd L,R,mid,ans=0;
    138     while(m--)
    139     {
    140         x=gint(),y=gint();
    141         L=0,R=1e5;
    142         while(R-L>=eps)
    143         {
    144             mid=(L+R)/2;
    145             if(cut::query(x,y,mid)>=0) ans=mid,L=mid+eps;
    146             else R=mid-eps;
    147         }
    148         printf("%.4lf
    ",ans);
    149     }
    150     return 0;
    151 }
  • 相关阅读:
    使用wchar_t输入,显示中文
    MFC使用rich edit若干问题
    一种对话框嵌入MFC 文档结构效果的实现方法(一),让你的自定义对话框区域同客户区大小一起改变
    一种在MFC程序上显示jpeg图片的方法(二)曙光乍现
    一种在MFC程序上显示jpeg图片的方法(一)宁滥勿缺
    MFC---GDI之DC类杂记,以画尺子为例
    又让厂公着半天急----一例自定义MFC程序编译时LNK2019错误
    egret 引擎分析之三————egret make --egretversion xxxx 到底做了什么?
    egret 引擎分析之二————从selector.js说起
    egret 引擎分析之一————egret 命令的时候发生了什么
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10151587.html
Copyright © 2020-2023  润新知