ZOJ 3606 Lazy Salesgirl 浙江省第九届省赛
Kochiya Sanae is a lazy girl who makes and sells bread. She is an expert at bread making and selling. She can sell the i-th customer some pieces of bread at price pi for each piece. But she is so lazy that she will fall asleep if no customer comes to buy bread for more than w minutes. When she is sleeping, the customer coming to buy bread will wake her up and leave without buying anything. Once she is woken up, she will start to sell bread again until she encounters another gap of w minutes. What's more weird, she can sell 1 + ((k - 1) mod 3)
pieces of bread when she sells at the k-th time. It's known that she starts to sell bread now and the i-th customer comes after ti minutes. What is the minimum possible value of w that maximizes the average value of the bread sold each time?
Input
There are multiple test cases. The first line of input is an integer T ≈ 100 indicating the number of test cases.
The first line of each test case contains an integer 1 ≤ n ≤ 105 indicating the number of customers. The second line contains n integers 1 ≤ pi ≤ 106. The third line contains n integers 1 ≤ ti ≤ 107. All ti are different.
Output
For each test cases, output w and the corresponding average value of sold bread, with six decimal digits.
Sample Input
2 4 1 2 3 4 1 3 6 10 4 1 2 3 4 4 7 9 10
Sample Output
3.000000 4.666667 3.000000 6.666667
AC代码:线段树
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 const int N = 1e5+10; 7 const int W = 3; 8 int sum[N*4]; 9 long long get[W+1][N*4]; 10 double ansg,anst; 11 #define left l,m,x<<1 12 #define right m+1,r,x<<1|1 13 struct TT 14 { 15 int p,t; 16 bool operator<(const TT &y) const 17 { 18 return t<y.t; 19 } 20 21 }pre[N]; 22 struct pp 23 { 24 int id,w; 25 bool operator<(const pp &y) const 26 { 27 return w<y.w; 28 } 29 }mm[N]; 30 void init() 31 { 32 ansg = anst = 0.0; 33 memset(sum,0,sizeof(sum)); 34 memset(get,0,sizeof(get)); 35 } 36 void pushup(int x) 37 { 38 sum[x] = sum[x<<1] +sum[x<<1 | 1]; 39 int tem,i; 40 for(i=1;i<=W;i++) 41 { 42 tem = (i+sum[x<<1]-1)%W+1; 43 get[i][x] = get[i][x<<1]+get[tem][x<<1 | 1]; 44 } 45 } 46 void update(int pos,long long p,int l,int r,int x) 47 { 48 if(l == r) 49 { 50 sum[x]++; 51 for(int i=1;i<=W;i++) 52 get[i][x] = i*p; 53 return ; 54 } 55 int m = (l+r)>>1; 56 if(pos<=m) update(pos,p,left); 57 if(pos>m) update(pos,p,right); 58 pushup(x); 59 } 60 int main() 61 { 62 int T,i,j,n; 63 double tem; 64 scanf("%d",&T); 65 while(T--) 66 { init(); 67 scanf("%d",&n); 68 for( i=0;i<n;i++) scanf("%d",&pre[i].p); 69 for( i=0;i<n;i++) scanf("%d",&pre[i].t); 70 sort(pre,pre+n);//对到来的时间进行排序 71 mm[0].w = pre[0].t; 72 mm[0].id = 0; 73 for( i=1;i<n;i++) 74 { 75 mm[i].w = pre[i].t - pre[i-1].t;//取时间差,然后相减,再对时间差进行排序; 76 mm[i].id = i; 77 } 78 sort(mm,mm+n); 79 for( i=0;i<n;) 80 { 81 j=i; 82 while(j<n && mm[i].w == mm[j].w) 83 { 84 update(mm[j].id,pre[mm[j].id].p,0,n-1,1); 85 j++; 86 } 87 tem = get[1][1]*1.0/sum[1]; 88 if(ansg <tem) 89 { 90 ansg = tem; 91 anst = mm[i].w; 92 } 93 i=j; 94 } 95 printf("%.6lf %.6lf\n",anst,ansg); 96 } 97 return 0; 98 }