BZOJ 2600: [Ioi2011]ricehub

2600: [Ioi2011]ricehub

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 628  Solved: 325
[Submit][Status][Discuss]

Description

乡间有一条笔直而长的路称为“米道”。沿着这条米道上 R 块稻田,每块稻田的坐标均
为一个 1 到 L 之间(含 1 和 L)的整数。这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <
R,稻田 i 的坐标 X[i]满足 1 ≤ X[0] ≤ ... ≤ X[R-1] ≤ L。 
注意:可能有多块稻田位于同一个坐标上。 
我们计划建造一个米仓用于储存尽可能多的稻米。和稻田一样,米仓将建在米道上,其
坐标也是一个 1 到 L 之间的整数(含 1 和 L)。这个米仓可以建在满足上述条件的任一个位
置上,包括那些原来已有一个或多个稻田存在的位置。 
在收获季节,每一块稻田刚好出产一滿货车的稻米。为了将这些稻米运到米仓,需要雇
用一位货车司机来运米。司机的收费是每一满货车运送一个单位的距离收取 1 元。換言之,
将稻米从特定的稻田运到米仓的费用在数值上等于稻田坐标与米仓坐标之差的绝对值。 
不幸的是,今年预算有限,我们至多只能花费 B 元运费。你的任务是要帮我们找出一个
建造米仓的位置,可以收集到尽可能多的稻米。

Input

第一行 三个整数 R L B
接下来R行 每行一个整数 表示X[i]

Output

一个整数 最多稻米数

Sample Input

5 20 6
1
2
10
12
14

Sample Output

3
HINT
1 ≤ R ≤ 100,000
1 ≤ L ≤ 1,000,000,000

0 ≤ B ≤ 2,000,000,000,000,000


这个题目居然在我们学校讲课时被归类为了二分(没认真听课QAQ不知道是怎么兹磁的啊)%%

显然易得出我们选取的米仓一定收集的一段连续的区间,而米仓一定是在这段区间的中位数上。

我们将右区间r从1到R枚举,每一次维护的左区间l。

记res为剩余的钱数。如果res小于0则左区间右移(即序列最早入队的稻田出队),直到res大于0。中位数可以O(1)的转移。

关于复杂度:因为每一个稻田至多只有入队和出队两次操作,所以复杂度为O(n)


 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #define llg long long
 9 #define yyj(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout);
10 #define maxn 100010
11 using namespace std;
12
13 llg sc()
14 {
15     llg i=0;char c=getchar();
16     while(c>‘9‘||c<‘0‘)c=getchar();
17     while(c>=‘0‘&&c<=‘9‘)i=i*10+c-‘0‘,c=getchar();
18     return i;
19 }
20
21 llg x,i,j,k,n,l,r,mid,m,a[maxn],ans;
22 double res,b,wz,lastwz;
23 int main()
24 {
25     yyj("a");
26     cin>>n>>m>>b;
27     for (i=1;i<=n;i++) a[i]=sc();
28     res=b;
29     x=1;
30     ans=1;
31     l=0; lastwz=a[1];
32     for (r=2;r<=n;r++)
33         {
34             if (a[r]>m) break;
35             x++;
36             if (x % 2) wz=a[l+x/2+1]; else wz=(double)(a[l+x/2]+a[l+x/2+1])/2;
37             if (x % 2==0) res-=(wz-lastwz);
38             res-=a[r]-wz; lastwz=wz;
39             while (res<0)
40                 {
41                     x--; l++; res+=lastwz-a[l];
42                     if (x % 2) wz=a[l+x/2+1]; else wz=(a[l+x/2]+a[l+x/2+1])/2;
43                     if (x % 2) res+=wz-lastwz;
44                     lastwz=wz;
45                 }
46             ans=max(ans,x);
47         }
48     cout<<ans;
49     return 0;
50 }
时间: 2024-08-23 14:58:26

BZOJ 2600: [Ioi2011]ricehub的相关文章

BZOJ 2600 IOI2011 ricehub 中位数

题目大意:给定一条道路上的n个稻田,要求建一个粮仓,并且选定一些稻田进行运输,这些稻田到粮仓的距离之和不能超过B,求最多能选择多少个稻田 维护一个队列,头指针从前到后扫一遍 如果发现尾指针到头指针这段稻田的中位数上建一个粮仓时距离之和超过了B,就调整尾指针 对距离维护一个前缀和 每次取中位数之后可以O(1)计算距离和 #include <cstdio> #include <cstring> #include <iostream> #include <algorit

bzoj 2600 ricehub

2600: [Ioi2011]ricehub Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 783  Solved: 417[Submit][Status][Discuss] Description 乡间有一条笔直而长的路称为"米道".沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <R,稻田 i 的坐标 X[i]满足 1 ≤ X[

[Ioi2011]ricehub

2600: [Ioi2011]ricehub Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <R,稻田 i 的坐标 X[i]满足 1 ≤ X[0] ≤ ... ≤ X[R-1] ≤ L. 注意:可能有多块稻

【BZOJ2600】[Ioi2011]ricehub 双指针法

[BZOJ2600][Ioi2011]ricehub Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <R,稻田 i 的坐标 X[i]满足 1 ≤ X[0] ≤ ... ≤ X[R-1] ≤ L. 注意:可能有多块稻田位于同一个坐标上. 我们计划建造一个米仓用于储存尽可能多的稻米.和稻田一样,米仓将建在米道上,其坐标也是一个 1 到 L

BZOJ 2600 IOI 2011 ricehub 二分

题目大意:给出粮食的位置,给出初始的钱数,问粮仓设在哪里会让收到的粮食最多.粮食运到粮仓需要花费|x - x'|的费用. 思路:看到L和B的范围都大的惊人,只能从R来下手.能不能从每个粮食的位置入手来搞点什么. 首先要想收购的尽量多,收购的粮食应该是一段连续的区间.对于每个粮食的位置,以这个粮食的位置为起点所能够收购到的粮食是单调的.这个就可以二分来确定了.一段区间内到达所有点最近的点是中位数,所以就可以O(1)判断了. (这真的是IOI题么.. CODE: #include <cstdio>

BZOJ 2599: [IOI2011]Race( 点分治 )

数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新CNT数组和答案. ------------------------------------------------------------------------------------------ #include<bits/stdc++.h> using namespace std; typ

bzoj2600 [Ioi2011]ricehub

Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ≤ i <R,稻田 i 的坐标 X[i]满足 1 ≤ X[0] ≤ ... ≤ X[R-1] ≤ L. 注意:可能有多块稻田位于同一个坐标上. 我们计划建造一个米仓用于储存尽可能多的稻米.和稻田一样,米仓将建在米道上,其坐标也是一个 1 到 L 之间的整数(含 1 和 L).这个米仓可以建在满足上述

【刷题】BZOJ 2599 [IOI2011]Race

Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始) Output 一个整数 表示最小边数量 如果不存在这样的路径 输出-1 Sample Input 4 3 0 1 1 1 2 2 1 3 4 Sample Output 2 Solution 点分治 考虑如何计算答案,有一个节点,我

bzoj 2599 [IOI2011]Race (点分治)

[题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] },y属于前S-1个子树,dis[x]<=K 所以只需要用一个数组t[len]记录前S-1棵子树中长度为len的最少边数即可.t只用开到K的最大值. 然后分治处理子树. [代码] 1 #include<set> 2 #include<cmath> 3 #include<qu