codeforces 的一道题 RMQ_ST

D. dir -C
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Famous Berland coder and IT manager Linus Gates announced his next proprietary open-source system "Winux 10.04 LTS"

In this system command "dir -C" prints list of all files in the current catalog in multicolumn mode.

Lets define the multicolumn mode for number of lines l. Assume that filenames are already sorted lexicographically.

  • We split list of filenames into several continuous blocks such as all blocks except for maybe last one consist of l filenames, and last block consists of no more than l filenames, then blocks are printed as columns.
  • Width of each column wi is defined as maximal length of the filename in appropriate block.
  • Columns are separated by 1 × l column of spaces.
  • So, width of the output is calculated as , i.e. sum of widths of each column plus number of columns minus one.

Example of multi-column output:

a       accd e t
aba     b    f wtrt
abacaba db   k

In the example above width of output is equal to 19.

"dir -C" command selects minimal l, such that width of the output does not exceed width of screen w.

Given information about filename lengths and width of screen, calculate number of lines l printed by "dir -C" command.

Input

First line of the input contains two integers n and w — number of files in the list and width of screen (1 ≤ n ≤ 1051 ≤ w ≤ 109).

Second line contains n integers fi — lengths of filenames. i-th of those integers represents length of i-th filename in the lexicographically ordered list (1 ≤ fi ≤ w).

Output

Print one integer — number of lines l, printed by "dir -C" command.

Examples
input
11 20
1 3 7 4 1 2 1 1 1 1 4
output
3

意思就是竖着填文件名,每个单词的长度是a[i],给定了边框长度,问你最少需要多少行才能列出这么多文件名(最后一列后面没有空格)。

因为题中命令有对其形式,所以需要求出区间最值,并且是多次询问。比赛的时候我准备暴力做,无奈做是做对了但是肯定TLE没跑,后来一想,尼玛多次询问不就是RMQ么,线段树不会,没关系老子会st啊!事实证明的确是st,因为尼玛这么大数据线段树还可能开不了那么大。所以就打st,因为最后没有时间了,最后打出来了但是提交不上去(提交上去也是错的),所以回家做。

回家做的结果就是这样。。

没错,第一次ac还是照着别人的比着比着做出来的,然后我又打了很多遍终于皇天不负有心人又wa了几发后对了。。。


这回我终于找到bug出在哪了。

当你有n个数从0 ~ n - 1时,你的st表的st[n - 1][k(k >= 1)]就会是0,因为n - 1 + 2^k 已经超过了n,不会继续往下算了。所以在query的时候肯定会出错!因为尼玛除了st[n - 1][0]之外的st[n - 1][k]都tm是0啊!不说了 说出来都是泪,我也是够蠢了。贴代码吧。

/*
* Head_File_For_Eclipse
*
*  Created on: 2016年2月20日
*      Author: Triose
*/
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<map>
#include<set>
using namespace std;
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define inf 0x3f3f3f3f
#define rep(i,a) for((i)=0; i<(a);(i)++)
#define mem(a,b) (memset((a),b,sizeof(a)))
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sfs(a) scanf("%s",a)
#define pf(a) printf("%d\n",a)
#define pfs(a) printf("%s\n",a)
#define pfI(a) printf("%I64d\n",a)
#define enter putchar(10)
#define LL __int64
const double PI = acos(-1.0);
const double E = exp(1.0);
template<class T> T gcd(T a, T b) { return b ? gcd(b, a%b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b)*b; }
template<class T> inline T Min(T a, T b) { return a<b ? a : b; }
template<class T> inline T Max(T a, T b) { return a>b ? a : b; }
int n, m;
#define N 100010
int dp[N][20];
void rmq_init() {
	for (int i = 0; i < n; i++) {
		sf(dp[i][0]);
	}
	for (int j = 1; (1 << j) <= n; j++) {
		for (int i = 0; i + (1 << j) <= n; i++) {
			dp[i][j] = Max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
			if(i + 1 + (1 << j) > n) {
				dp[i + 1][j] = dp[i][j];
			}
		}
	}
}
int st(int u, int v) {			//[u, v]  这里最好还是闭区间吧
	int k = (int)log2((v > n ? n : v) - u + 1.0);
	return Max(dp[u][k], dp[(v > n ? n : v) - (1 << k) + 1][k]);
}
bool check(int line) {
	if (line == n)
		return true;
	int sum = 0;
	int l = 0;
	while (l < n) {
		sum += st(l, l + line - 1) + 1;
		if (sum > m) {
			return false;
		}
		l += line;
	}
	return true;
}
void DEBug() {<span style="white-space:pre">			</span>//最后实在没法了就一个一个的debug。。终于给我找出来了
	int u,v;
	while(~sfd(u,v)) {
		pf(st(u,v));
	}
	enter;
	enter;
}
int main() {
	while (~sfd(n, m)) {
		m++;
		mem(dp, 0);
		rmq_init();
//		DEBug();
		for (int line = 1; line <= n; line++) {
			if (check(line)) {
				pf(line);
				break;
			}
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值