二分与分治

好神啊好神啊.....

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

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

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

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

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

 

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 ...

...

原文地址:https://www.cnblogs.com/DragoonKiller/p/4564447.html