• zoj3606


      1 /*
      2 题意:售货员每隔w分钟就会睡觉,如果售货员睡着了那么顾客会叫醒她但是不会买东西,
      3 有n个客人会不同时间来,并且售货员卖给第i的客人的价格为p[i],并且售货员会在第k次卖
      4 出1+(k-1)%3个面包,求问最小的w使平均每次卖出的面包的价格最大即总收入/卖的次数;
      5 
      6 分析:如果w小于最小的时间间隔,那么售货员不会卖出一个面包显然不是最优的,
      7 当w>某一个时间间隔,那么会买面包的顾客都是时间间隔小于w的,
      8 显然最后答案肯定是某一个顾客的时间间隔,枚举要O(n^2),肯定超时;
      9 我们知道当w按顾客时间间隔递增,那么前面会买面包的顾客后面还是同样会买的,
     10 改变的只是卖的面包的个数,
     11 
     12 现在要完成的工作就是 单点更新,然后按照1,2,3,1,2,3的个数卖,求总收入和总买的次数
     13 
     14 我们可以通过线段树来完成这个工作,
     15 定义c[N<<2][3]和pos[N<<2];
     16 c[i][0]表示线段i起始位置顾客买1个面包,总的收入;
     17 c[i][1]表示线段i起始位置顾客买2个面包,总的收入;
     18 c[i][2]表示线段i起始位置顾客买3个面包,总的收入;
     19 pos[i]表示线段i里买面包的顾客的人数 
     20 
     21 这样就可以通过c[rt<<1][]和c[rt<<1|1][],来递推c[rt][];
     22 具体见代码;可以手推枚举一下;  
     23 trick:读入的时间不是按照顺序来的,要先排序,这个trick虽然很常见
     24 但是如果一不小心还是很容易掉进去不能自拔的;
     25  
     26 
     27 */
     28 #include<cstdio> 
     29 #include<cstring>
     30 #include<cstdlib>
     31 #include<iostream>
     32 #include<algorithm>
     33 #include<vector>
     34 #include<map>
     35 #define lson l,m,rt<<1
     36 #define rson m+1,r,rt<<1|1
     37 using namespace std;
     38 typedef long long LL;
     39 const int N=100000+10;
     40 const double eps=1e-10;
     41 LL c[N<<2][3];
     42 int pos[N<<2];
     43 vector<int> x,g[N];
     44 int n,n1;
     45 struct node{
     46     int pi,ti;
     47     bool operator < (const node&p)const{
     48         return ti<p.ti;
     49     }
     50 }nd[N];
     51 void init(){
     52     x.clear();
     53     for (int i=1;i<=n;i++){
     54         scanf("%d",&nd[i].pi);
     55     }    
     56     nd[0].ti=0;
     57     for (int  i=1;i<=n;i++){
     58         scanf("%d",&nd[i].ti);
     59     }
     60     sort(nd+1,nd+n+1);
     61     for (int i=1;i<=n;i++){
     62         x.push_back(nd[i].ti-nd[i-1].ti);
     63     }
     64     sort(x.begin(),x.end());
     65     n1=unique(x.begin(),x.end())-x.begin();
     66     for (int i=0;i<=n1;i++) g[i].clear();
     67     for (int i=1;i<=n;i++){
     68         int tmp=lower_bound(x.begin(),x.begin()+n1,nd[i].ti-nd[i-1].ti)-x.begin();
     69         g[tmp].push_back(i);
     70     }
     71     //cout<<"*** "<<endl;
     72     //for (int i=0;i<n1;i++) cout<<x[i]<<" ";cout<<endl;
     73 }
     74 void pushup(int rt){
     75     int t;
     76     pos[rt]=pos[rt<<1]+pos[rt<<1|1];
     77     t=pos[rt<<1]%3;
     78     for (int i=0;i<3;i++)
     79         c[rt][i]=c[rt<<1][i]+c[rt<<1|1][(t+i)%3];
     80     
     81 }
     82 void update(int L,int l,int r,int rt){
     83     if (l==r){
     84         c[rt][0]=nd[l].pi;
     85         c[rt][1]=nd[l].pi*2;
     86         c[rt][2]=nd[l].pi*3;
     87         pos[rt]=1;
     88         return;
     89     }
     90     int m=(l+r)>>1;
     91     if (L<=m) update(L,lson);
     92     else update(L,rson);
     93     pushup(rt);
     94 }
     95 void work(){
     96     LL ret1=0,ret2=0,ret3;
     97     memset(c,0,sizeof(c));
     98     memset(pos,0,sizeof(pos));
     99     for (int i=0;i<n1;i++){
    100         int sz=g[i].size();
    101         if (sz!=0){
    102             for (int j=0;j<sz;j++){
    103                 int v=g[i][j];
    104                 update(v,1,n,1);
    105             }
    106             //double tmp=(double)c[1][0]/pos[1];
    107         //    cout<<i<<" ** "<<c[1][0]<<" "<<pos[1]<<endl;
    108             if (ret1==0 || c[1][0]*ret2>ret1*pos[1]) {
    109                 ret1=c[1][0];
    110                 ret2=pos[1];
    111                 ret3=x[i];
    112             }
    113         }
    114     }    
    115     printf("%.6lf %.6lf\n",(double)ret3+eps,(double)ret1/ret2+eps);
    116 }
    117 int main(){
    118     int T;scanf("%d",&T);
    119     while (T--){
    120         scanf("%d",&n);
    121         init();
    122         work();    
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    hdu 1312 Red and Black
    hdu 1573 X问题
    广工校赛决赛之简单的数论题
    最大的LeftMax与rightMax之差绝对值
    POJ 2385 Apple Catching
    hdu 1171 Big Event in HDU
    ACM比赛经验
    BestCoder Valentine's Day Round
    使用ffmpeg进行视频封面截取
    使用ODP.NET连接Oracle数据库
  • 原文地址:https://www.cnblogs.com/Rlemon/p/3085437.html
Copyright © 2020-2023  润新知