IOI 2011 Rice Hub 米仓
Posted OptimusPrime_L
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOI 2011 Rice Hub 米仓相关的知识,希望对你有一定的参考价值。
题目
分析
首先来观察一下这题的数据范围,Subtask 4当中的数据量10^15大到惊人的程度。很显然这是我们所不能够处理的数据量。但转而看R的大小,就令人能够接受了,那么不难想到,这里有一个离散化的思路。
然后我们考虑如何安排这个米仓。这个米仓其实就相当于一个“中位数”,也就是安排在米仓能够处理的区间的正当中。
这里出现了一个“区间”的概念,那么我们就可以想到用一个类似二分的思想来枚举区间的左右边界。
首先O(R)枚举左边界,然后嵌一个while查右边界,写一个check函数来检查这个区间的可行性。check当中其实就是利用一个前缀和来计算钱数,然后和预算比较,返回true or false。
程序
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int MAXN = 100000 + 10; 4 long long S[MAXN], R, x[MAXN], r, b, ans, t; 5 bool check(int Left, int Right) 6 { 7 int hub_pos = (Left + Right) >> 1; 8 long long Cost=1ll*x[hub_pos]*(hub_pos-Left+1)-S[hub_pos]+S[Left-1]+S[Right]-S[hub_pos]-1ll*x[hub_pos]*(Right-hub_pos); 9 if (Cost <= b) 10 return true; 11 return false; 12 } 13 int main() 14 { 15 freopen("ricehub.in","r",stdin); 16 freopen("ricehub.out","w",stdout); 17 cin >> r >> t >> b; 18 for (int i = 1; i <= r; i++) 19 { 20 cin >> x[i]; 21 S[i] = S[i-1] + x[i]; 22 } 23 R = 1; 24 for (int L = 1; L <= r; L++) 25 { 26 while (R <= r && check(L,R)) 27 R++; 28 ans = max(ans, R-L); 29 } 30 cout << ans << endl; 31 return 0; 32 }
以上是关于IOI 2011 Rice Hub 米仓的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 2600: [Ioi2011]ricehub|暴力|中位数