Gym 100917J --- dir, gym100917j --- dir
Question Link
Http://codeforces.com/gym/100917/problem/D
Problem description
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 linesL. Assume that filenames are already sorted lexicographically.
- We split list of filenames into several continuous blocks such as all blocks cannot for maybe last one consistLFilenames, and last block consists of no moreLFilenames, then blocks are printed as columns.
- Width of each columnWIIs defined as maximal length of the filename in appropriate block.
- Columns are separated by 1 partition × PartitionLColumn 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 minimalL, Such that width of the output does not exceed width of screenW.
Given information about filename lengths and width of screen, calculate number of linesLPrinted by "dir-C" command.
Input
First line of the input contains two integersNAndW-Number of files in the list and width of screen (1 limit ≤ limitNLimit ≤ limit 105, 1 limit ≤ limitWLimit ≤ limit 109 ).
Second line containsNIntegersFI-Lengths of filenames.I-Th of those integers represents lengthI-Th filename in the lexicographically ordered list (1 limit ≤ limitFILimit ≤ limitW).
Output
Print one integer-number of linesL, Printed by "dir-C" command.
ExamplesInput
11 20
1 3 7 4 1 2 1 1 1 1 4
Output
3
Contains n directory name strings. The length is a [1] ~ The screen width of a [n] is w. Now we need to put one column and one column in sequence according to the given directory, and x in each column, the last column is placed <= x, which requires the directory names in each column to be neatly arranged on the left side to form a rectangular block. The block and block are empty and cannot exceed the screen width, calculates the minimum number of rows;
Idea: First process the input length, use ST to calculate the maximum value of each interval, and then enumerate the number of rows x from 1 ~ N;
The Code is as follows:
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <map>#include <cmath>using namespace std;typedef long long LL;const int MAXN = 1e5+5;int a[MAXN],m[30][MAXN];int n;LL w;int main(){ while(scanf("%d%I64d",&n,&w)!=EOF) { memset(m,0,sizeof(m)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); m[0][i]=a[i]; } for(int i=1;i<=(int)log(n)/log(2);i++) { for(int j=1;j+(1<<i)-1<=n;j++) m[i][j]=max(m[i-1][j],m[i-1][j+(1<<(i-1))]); } for(int i=1;i<=n;i++) { int k=(int)log(i); long long sum=0; for(int j=0;j<n/i;j++) { sum+=(long long)max(m[k][j*i+1],m[k][i*(j+1)-(1<<k)+1])+1; } if(n%i!=0) { k=(int)log(n%i); sum+=(long long)max(m[k][n-n%i+1],m[k][n-(1<<k)+1])+1; } if(sum-1<=w){ printf("%d\n",i); break; } } } return 0;}