zoukankan      html  css  js  c++  java
  • 二分与分治

    好神啊好神啊.....

    大概就是,对于一个询问,我们可以二分答案求出结果的话......

    那么对于一大堆询问,我们一起二分它们的答案......

    然后,我们通过某种简化的判定条件来决定询问应该被分到左边还是右边.

    把当前处理的询问扫一遍,求出应该往左递归的询问和往右递归的询问. 然后把左边的询问堆到一起,往下传.

    注意我们可能需要维护一些附加信息.....看题...

     

    AC VIJOS 1081 野生动物园

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21  
     22 using namespace std;
     23  
     24 inline int getint()
     25 {
     26     int res=0;
     27     char c=getchar();
     28     bool mi=false;
     29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     31     return mi ? -res : res;
     32 }
     33 inline ll getll()
     34 {
     35     ll res=0;
     36     char c=getchar();
     37     bool mi=false;
     38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     40     return mi ? -res : res;
     41 }
     42 
     43 //==============================================================================
     44 //==============================================================================
     45 //==============================================================================
     46 //==============================================================================
     47 
     48 const int INF=(1<<30)-1;
     49 
     50 int n,m;
     51 
     52 struct query
     53 { int l,r,k,res; int id; };
     54 query op[50050];
     55 bool cmp(const query&a,const query&b)
     56 { return a.id < b.id; }
     57 
     58 int a[100050];
     59 int loc[100050];
     60 int cnt[100050];
     61     
     62 void DC(query*q,int qcnt,int*p,int pcnt,int l,int r)
     63 {
     64     if(qcnt==0) return ;
     65     if(l==r) { for(int i=0;i<qcnt;i++) q[i].res=l; return ; }
     66     
     67     int mid=(l+r)>>1;
     68     
     69     //solve. count amount of number larger than s
     70     // for each operation in Q.
     71     
     72     //pre process for count.
     73     int tot=0;
     74     for(int i=0;i<pcnt;i++) 
     75     if(a[p[i]]<=mid) loc[tot++]=p[i];
     76     sort(loc,loc+tot);
     77     loc[tot++]=INF;
     78     
     79     //count.
     80     for(int i=0;i<qcnt;i++)
     81     cnt[i]=int(upper_bound(loc,loc+tot,q[i].r)-lower_bound(loc,loc+tot,q[i].l));
     82     
     83     int vt=0;
     84     int qt=0; //these are the COUNTERs
     85     for(int i=0;i<pcnt;i++) if(a[p[i]]<=mid) swap(p[vt],p[i]),vt++;
     86     for(int i=0;i<qcnt;i++) 
     87         if(q[i].k<=cnt[i]) swap(q[i],q[qt]),qt++;
     88         else q[i].k-=cnt[i];
     89     
     90     DC(q,qt,p,vt,l,mid);
     91     DC(q+qt,qcnt-qt,p+vt,pcnt-vt,mid+1,r);
     92 }
     93 
     94 int preloc[100050];
     95 
     96 int main()
     97 {
     98     n=getint();
     99     m=getint();
    100     int miv=INF;
    101     int mxv=-INF;
    102     for(int i=0;i<n;i++)
    103     a[i]=getint(),mxv=max(mxv,a[i]),miv=min(miv,a[i]);
    104     for(int i=0;i<m;i++)
    105     {
    106         int l=getint()-1;
    107         int r=getint()-1;
    108         int k=getint();
    109         op[i]=(query){l,r,k,0,i};
    110     }
    111     
    112     for(int i=0;i<n;i++) preloc[i]=i;
    113     DC(op,m,preloc,n,miv,mxv);
    114     
    115     sort(op,op+m,cmp);
    116     
    117     for(int i=0;i<m;i++)
    118     printf("%d
    ",op[i].res);
    119     
    120     return 0;
    121 }
    View Code

    找个简单题练手.......

     

    看哈,我们二分操作不是要对每个询问判断:在区间中,有多少个数比mid小嘛?

    那么我们把这个区间里面所有的数扫一遍,统计比mid大的数的个数.

    但是多个询问不允许我们直接扫.

     

    论文给出的解决方法是,

    求出所有能力值属于当前二分到的权值区间(l,mid)的狮子的下标.

    对其排序并用询问的区间进行二分. upper_bound-lower_bound就行了.

    这样可以用 $log$ 级别的时间求出每个区间的比mid小的数的个数.

    运用整体二分算法的关键就在于此. 我们加速的方式,就是快速求出一堆询问的二分判定.

    简单地说,就是,给你一堆询问,问你,哪些询问的结果应该被分到左区间? 哪些在右区间?

    解决这个问题的复杂度如果为 $f(k)$ ,那么算法总的复杂度为 $f(n)log{v}$ .

    最终复杂度是 $O(log{v} log{n}( m+n))$ ,比可持久化线段树慢三分之一.

     

    AC POI2011 Meteors

    从这里看的题目和题解 http://victorwonder.is-programmer.com/posts/70210.html?utm_source=tuicool

    讲得非常清楚..... 然后题目可以在下边这个网站交......

    http://main.edu.pl/en

     神奇的网站.....神奇的题库.....神奇的题目....

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21  
     22 using namespace std;
     23  
     24 inline int getint()
     25 {
     26     int res=0;
     27     char c=getchar();
     28     bool mi=false;
     29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     31     return mi ? -res : res;
     32 }
     33 inline ll getll()
     34 {
     35     ll res=0;
     36     char c=getchar();
     37     bool mi=false;
     38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     40     return mi ? -res : res;
     41 }
     42 
     43 //==============================================================================
     44 //==============================================================================
     45 //==============================================================================
     46 //==============================================================================
     47 
     48 const ll INF=((ll)1<<56)-1;
     49 
     50 
     51 int n,m,k;
     52 
     53 
     54 ll cty[305000]; //station belongs to
     55 ll ask[305000]; //meteors asked for countries.
     56 
     57 struct op
     58 { int l,r; ll v; } M[305000];
     59 
     60 struct edge { int in; edge*nxt; };
     61 int ecnt=5000; edge*et;
     62 edge*eds[305000];
     63 void addedge(int a,int b)
     64 {
     65     if(ecnt==5000){ecnt=0;et=new edge[5000];}
     66     et->in=b; et->nxt=eds[a]; eds[a]=et++; ecnt++;
     67 }
     68 #define FOREACH_SON(i,x) for(edge*i=eds[x];i;i=i->nxt) 
     69 
     70 int stp[305000];
     71 int res[305000];
     72 
     73 struct SegTree
     74 {
     75     ll tag[1205000]; //SegTree tags
     76     int cl,cr; ll cv;
     77     void Change(int x=1,int l=0,int r=m-1)
     78     {
     79         if(cl<=l && r<=cr) { tag[x]+=cv; return ; }
     80         int mid=(l+r)>>1;
     81         if(mid>=cl) Change(x<<1,l,mid);
     82         if(mid<cr) Change(x<<1|1,mid+1,r);
     83     }
     84     ll Query(int p)
     85     {
     86         int x=1,l=0,r=m-1;
     87         ll res=0;
     88         while(l!=r)
     89         {
     90             res+=tag[x];
     91             if(res>INF) break;
     92             int mid=(l+r)>>1;
     93             if(p<=mid) { x<<=1; r=mid; }
     94             else { x=x<<1|1; l=mid+1; } 
     95         }
     96         res+=tag[x];
     97         return res;
     98     }
     99 }T;
    100 
    101 ll dc[605000];
    102 void DC(int*p,int pt,int l,int r)
    103 {
    104     if(l==r) { for(int i=0;i<pt;i++) res[p[i]]=l; return ; }
    105     
    106     int mid=(l+r)>>1;
    107     
    108     //brute force to deal with the querys.
    109     for(int i=l;i<=mid;i++)
    110     {
    111         T.cv=M[i].v;
    112         
    113         if(M[i].l<=M[i].r)
    114         T.cl=M[i].l,T.cr=M[i].r,T.Change();
    115         else
    116         {
    117             T.cl=M[i].l,T.cr=m-1,T.Change();
    118             T.cl=0,T.cr=M[i].r,T.Change();
    119         }
    120     }
    121     
    122     for(int i=0;i<pt;i++) FOREACH_SON(e,p[i]) //....what's the complexity?
    123     { dc[p[i]]+=T.Query(e->in); if(dc[p[i]]>=ask[p[i]]) break; } 
    124     
    125     for(int i=l;i<=mid;i++)
    126     {
    127         T.cv=-M[i].v;
    128         
    129         if(M[i].l<=M[i].r)
    130         T.cl=M[i].l,T.cr=M[i].r,T.Change();
    131         else
    132         {
    133             T.cl=M[i].l,T.cr=m-1,T.Change();
    134             T.cl=0,T.cr=M[i].r,T.Change();
    135         }
    136     }
    137     
    138     int nxp=0;
    139     for(int i=0;i<pt;i++)
    140     if(dc[p[i]]>=ask[p[i]]) swap(p[i],p[nxp++]);
    141     
    142     for(int i=nxp;i<pt;i++)
    143     ask[p[i]]-=dc[p[i]]; //this will not meet the breaks above.
    144     
    145     for(int i=0;i<pt;i++)
    146     dc[p[i]]=0; //reverse edit.
    147     
    148     DC(p,nxp,l,mid);
    149     DC(p+nxp,pt-nxp,mid+1,r);
    150 }
    151 
    152 int main()
    153 {
    154     n=getint(); //amount of countries
    155     m=getint(); //amount of stations
    156     
    157     for(int i=0;i<m;i++)
    158     addedge(getint()-1,i); //set station i to country getint()-1;
    159     
    160     for(int i=0;i<n;i++)
    161     ask[i]=getint();
    162     
    163     k=getint();
    164     for(int i=0;i<k;i++)
    165     {
    166         M[i].l=getint()-1;
    167         M[i].r=getint()-1;
    168         M[i].v=getint();
    169     }
    170     M[k].l=0; M[k].r=m-1; M[k].v=INF; //to change all NIE into a solution.
    171     
    172     for(int i=0;i<n;i++) stp[i]=i; //pointers assign.
    173     DC(stp,n,0,k);
    174     
    175     for(int i=0;i<n;i++)
    176     if(res[i]==k) printf("NIE
    ");
    177     else printf("%d
    ",res[i]+1);
    178     
    179     return 0;
    180 }
    View Code

    实现用线段树,时间复杂度(大概)为 $O(log{v}log{m}n)$ 

    人家用树状数组比我快三倍TAT

     

    如果对单个询问进行二分,那就是二分一下时间,设中间的时间为 $mid$ .

    显然要对询问(就是每个国家的陨石收集量)进行统计. 直接暴力,对每组陨石使用线段树或者树状数组,

    维护区间和,询问单点值(嗯没错,把当前国家的空间站枚举一遍做统计就好了).......

    统计完以后,按照国家收集的陨石数量超过/不超过需求量,把国家分成左右两部分....

    然后,清空统计用的数组.注意一定要反向修改.....不能直接memset.....

     

    需要注意的地方....

    1.呃........动态加边加点一定要记得计数器加意加二什么的....!!!!!!

    2.我们在数组里边存的是当前考虑的国家的编号. 注意在我们的操作过程中要改变那个编号数组,所以统计数组绝对不能省掉编号!(就是说,程序中d[p[i]]不能被修改成d[i],如果不再附加数组记录一些信息的话.)

     

     


    cdq分治

    AC BZOJ 1492 NOI2007 Cash

    故意不去掉注释....这个题写的我想死啊........

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21 typedef long double ldb;
     22  
     23 using namespace std;
     24  
     25 inline int getint()
     26 {
     27     int res=0;
     28     char c=getchar();
     29     bool mi=false;
     30     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     31     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     32     return mi ? -res : res;
     33 }
     34 inline ll getll()
     35 {
     36     ll res=0;
     37     char c=getchar();
     38     bool mi=false;
     39     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     40     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     41     return mi ? -res : res;
     42 }
     43 
     44 //==============================================================================
     45 //==============================================================================
     46 //==============================================================================
     47 //==============================================================================
     48 
     49 inline double getdb()
     50 { double x; scanf("%lf",&x); return x; }
     51 
     52 struct point //also vector
     53 {
     54     ldb x,y; point(){} point(ldb a,ldb b):x(a),y(b){}
     55     ldb operator*(point f) { return x*f.y-y*f.x; }
     56     point operator-(point f) { return point(x-f.x,y-f.y); }
     57     point operator()(point f) { return point(f.x-x,f.y-y); }
     58 };
     59 
     60 inline bool ConvexChange(point&a,point&s1,point&s2)
     61 //Should s1 be thrown from convex when I add a new point a?
     62 { return s1(a)*s2(a)<=0.0; }
     63 
     64 inline bool SlopeBetter(point&a,point&b,ldb k)
     65 //Is a better than b when slope is k?
     66 { return a.y-b.y >= k*(a.x-b.x); }
     67 
     68 bool cmpdec(const ldb&a,const ldb&b)
     69 { return a>=b; }
     70 
     71 ldb d[105000];
     72 ldb A[105000];
     73 ldb B[105000];
     74 ldb R[105000];
     75 
     76 ldb X[105000];
     77 ldb Y[105000];
     78 ldb K[105000];
     79 bool kcmp(const int&a,const int&b)
     80 { return K[a]>=K[b]; }
     81 
     82 point s[105000]; int st;
     83 
     84 int h[105000]; //pointers for increasing slope.
     85 int q[105000]; //merge sort auxiliary array.
     86 int p[105000]; //pointers for increasing x coordinate.
     87 void DC(int l,int r)
     88 {
     89     if(l==r)  
     90     {
     91         d[l]=max(d[l-1],d[l]);
     92         Y[l]=d[l]/(R[l]*A[l]+B[l]);
     93         X[l]=Y[l]*R[l];
     94         //printf("solved: %d %.4f %.4f %.4f
    ",l,(db)d[l],(db)X[l],(db)Y[l]);
     95         return ;
     96     }
     97     int mid=(l+r)>>1;
     98     
     99     //divide h into two parts.
    100     //then throw the left part to the left DC.
    101     //and use right part for this function.
    102     //and throw right part to the right DC.
    103     //printf("[%d,%d]%d h(o):",l,r,mid); for(int i=l;i<=r;i++) printf("%d ",h[i]); printf("
    ");
    104     
    105     int p1=l,p2=mid+1;
    106     for(int i=l;i<=r;i++)
    107     if(h[i]<=mid) q[p1++]=h[i]; else q[p2++]=h[i];
    108     memcpy(h+l,q+l,sizeof(int)*(r-l+1));
    109     
    110     //printf("[%d,%d]%d h(d):",l,r,mid); for(int i=l;i<=r;i++) printf("%d ",h[i]); printf("
    ");
    111     
    112     DC(l,mid); //this will set queries in [l,mid] to correct ans.
    113     
    114     //build convex.
    115     st=0;
    116     s[st++]=point(0,0); //nothing to transfer.?
    117     for(int i=l;i<=mid;i++)
    118     {
    119         point c(X[p[i]],Y[p[i]]);
    120         //printf("coordinate of %d is (%.4f,%.4f)
    ",p[i],(db)X[p[i]],(db)Y[p[i]]);
    121         while(st>1 && ConvexChange(c,s[st-1],s[st-2])) st--;
    122         s[st++]=c;
    123     }
    124     
    125     //printf("Final Convex: ");for(int i=0;i<st;i++) printf("(%.4f,%.4f)",(db)s[i].x,(db)s[i].y); printf("
    ");
    126     
    127     //set queries in [mid+1,r] an answer.
    128     int t=0;
    129     //printf("h for trans: ");for(int i=mid+1;i<=r;i++) printf("%.4f ",(db)K[h[i]]); printf("
    ");
    130     //printf("[%d,%d] h for trans: ",l,r);for(int i=mid+1;i<=r;i++) printf("%d ",h[i]); printf("
    ");
    131     for(int i=mid+1;i<=r;i++)
    132     {
    133         int x=h[i];
    134         //printf("%.4f ",(db)K[x]);
    135         ldb k=K[x]; //notice that we should set K monotone decreasing.
    136         while(t<st-1 && SlopeBetter(s[t+1],s[t],k)) t++;
    137         d[x]=max(d[x],A[x]*s[t].x+B[x]*s[t].y);
    138         //printf("update %.4f %.4f for %d
    ",(db)s[t].x,(db)s[t].y,x);
    139     }
    140     //printf("end.
    ");
    141     
    142     DC(mid+1,r); //this will set queries in [mid+1,r] to correct ans.
    143     
    144     //set array p.
    145     //note that p is just for the next convex.
    146     //it's not what we're doing divide and conquar on.
    147     t=0;
    148     p1=l,p2=mid+1;
    149     while(p1<=mid && p2<=r)
    150     if(X[p[p1]]<X[p[p2]]) q[t++]=p[p1++]; else q[t++]=p[p2++];
    151     while(p1<=mid) q[t++]=p[p1++];
    152     while(p2<=r) q[t++]=p[p2++];
    153     memcpy(p+l,q,sizeof(int)*(r-l+1));
    154     
    155     //printf("[%d,%d] p(d):",l,r); for(int i=l;i<=r;i++) printf("%d ",p[i]); printf("
    ");
    156 }
    157 
    158 
    159 int n;
    160 
    161 int main()
    162 {
    163     freopen("in.txt","r",stdin);
    164     freopen("out.txt","w",stdout);
    165     
    166     n=getint();
    167     d[1]=d[0]=getdb();
    168     
    169     for(int i=1;i<=n;i++)
    170         A[i]=getdb(),
    171         B[i]=getdb(),
    172         R[i]=getdb();
    173     
    174     for(int i=1;i<=n;i++)
    175     K[i]=-(A[i]/B[i]);
    176     
    177     for(int i=0;i<=n;i++)
    178     h[i]=p[i]=i;
    179     
    180     stable_sort(h+1,h+n+1,kcmp);
    181     
    182     //for(int i=1;i<=n;i++) printf("%d A:%2.4f B:%2.4f R:%2.4f K:%2.4f
    ",i,(db)A[i],(db)B[i],(db)R[i],(db)K[i]);
    183     //for(int i=1;i<=n;i++) printf("%d %.4f
    ",h[i],(db)K[h[i]]);
    184     
    185     DC(1,n);
    186     
    187     cout.precision(3);
    188     cout<<fixed;
    189     cout<<d[n]<<endl;
    190     
    191     //for(int i=1;i<=n;i++) printf("resault of %d is %.4f
    ",i,(db)d[i]);
    192     
    193     return 0;
    194 }
    195 
    196 /*
    197 5 1.00
    198 12 8 3
    199 13 9 2
    200 13 9 2
    201 13 10 2
    202 13 8 3
    203 */
    View Code

    对归并操作和凸壳维护太不熟了.........还有各种指针(包括保存下标的伪指针) o(╯□╰)o ......

    听说有人被卡精度?于是我用了 long double ... 然而double也能A ......

    不过BZOJ上的 long double 真的是12位=.=

    还是把去掉注释的版本放上来吧.....

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21 typedef long double ldb;
     22  
     23 using namespace std;
     24  
     25 inline int getint()
     26 {
     27     int res=0;
     28     char c=getchar();
     29     bool mi=false;
     30     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     31     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     32     return mi ? -res : res;
     33 }
     34 inline ll getll()
     35 {
     36     ll res=0;
     37     char c=getchar();
     38     bool mi=false;
     39     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     40     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     41     return mi ? -res : res;
     42 }
     43 
     44 //==============================================================================
     45 //==============================================================================
     46 //==============================================================================
     47 //==============================================================================
     48 
     49 inline double getdb()
     50 { double x; scanf("%lf",&x); return x; }
     51 
     52 struct point //also vector
     53 {
     54     ldb x,y; point(){} point(ldb a,ldb b):x(a),y(b){}
     55     ldb operator*(point f) { return x*f.y-y*f.x; }
     56     point operator-(point f) { return point(x-f.x,y-f.y); }
     57     point operator()(point f) { return point(f.x-x,f.y-y); }
     58 };
     59 
     60 inline bool ConvexChange(point&a,point&s1,point&s2)
     61 { return s1(a)*s2(a)<=0.0; }
     62 
     63 inline bool SlopeBetter(point&a,point&b,ldb k)
     64 { return a.y-b.y >= k*(a.x-b.x); }
     65 
     66 bool cmpdec(const ldb&a,const ldb&b)
     67 { return a>=b; }
     68 
     69 ldb d[105000];
     70 ldb A[105000];
     71 ldb B[105000];
     72 ldb R[105000];
     73 
     74 ldb X[105000];
     75 ldb Y[105000];
     76 ldb K[105000];
     77 bool kcmp(const int&a,const int&b)
     78 { return K[a]>=K[b]; }
     79 
     80 point s[105000]; int st;
     81 
     82 int h[105000];
     83 int q[105000];
     84 int p[105000];
     85 void DC(int l,int r)
     86 {
     87     if(l==r)  
     88     {
     89         d[l]=max(d[l-1],d[l]);
     90         Y[l]=d[l]/(R[l]*A[l]+B[l]);
     91         X[l]=Y[l]*R[l];
     92         return ;
     93     }
     94     int mid=(l+r)>>1;
     95     
     96     int p1=l,p2=mid+1;
     97     for(int i=l;i<=r;i++)
     98     if(h[i]<=mid) q[p1++]=h[i]; else q[p2++]=h[i];
     99     memcpy(h+l,q+l,sizeof(int)*(r-l+1));
    100     
    101     DC(l,mid);
    102     
    103     st=0;
    104     s[st++]=point(0,0);
    105     for(int i=l;i<=mid;i++)
    106     {
    107         point c(X[p[i]],Y[p[i]]);
    108         while(st>1 && ConvexChange(c,s[st-1],s[st-2])) st--;
    109         s[st++]=c;
    110     }
    111     
    112     int t=0;
    113     for(int i=mid+1;i<=r;i++)
    114     {
    115         int x=h[i];
    116         ldb k=K[x];
    117         while(t<st-1 && SlopeBetter(s[t+1],s[t],k)) t++;
    118         d[x]=max(d[x],A[x]*s[t].x+B[x]*s[t].y);
    119     }
    120     
    121     DC(mid+1,r);
    122     
    123     t=0,p1=l,p2=mid+1;
    124     while(p1<=mid && p2<=r)
    125     if(X[p[p1]]<X[p[p2]]) q[t++]=p[p1++]; else q[t++]=p[p2++];
    126     while(p1<=mid) q[t++]=p[p1++];
    127     while(p2<=r) q[t++]=p[p2++];
    128     memcpy(p+l,q,sizeof(int)*(r-l+1));
    129 }
    130 
    131 int n;
    132 
    133 int main()
    134 {
    135     n=getint();
    136     d[1]=d[0]=getdb();
    137     
    138     for(int i=1;i<=n;i++)
    139         A[i]=getdb(),
    140         B[i]=getdb(),
    141         R[i]=getdb();
    142     
    143     for(int i=1;i<=n;i++)
    144     K[i]=-(A[i]/B[i]);
    145     
    146     for(int i=0;i<=n;i++)
    147     h[i]=p[i]=i;
    148     
    149     stable_sort(h+1,h+n+1,kcmp);
    150     
    151     DC(1,n);
    152     
    153     cout.precision(3);
    154     cout<<fixed;
    155     cout<<d[n]<<endl;
    156     
    157     return 0;
    158 }
    View Code

    用 long double 只比 double 慢了总共 88ms ...

    ...

  • 相关阅读:
    一个提高N倍系统新能的编程点,却总是被普通开发们遗忘
    工作不到一年,做出了100k系统,老板给我升职加薪
    offer收割机也有方法论
    最长公共前缀
    罗马数字转整数
    回文数
    整数反转
    两数之和
    网页中Office和pdf相关文件导出
    搭建一个低配版的Mock Server
  • 原文地址:https://www.cnblogs.com/DragoonKiller/p/4564447.html
Copyright © 2011-2022 走看看