Problem:
Score : 300 points

Problem Statement

You are given an integer N.
Find the number of the positive divisors of N!, modulo 10^9+7.

Constraints

1≤N≤10^3

Input

The input is given from Standard Input in the following format:

N

Output

Print the number of the positive divisors of N!, modulo 10^9+7.

Sample Input 1

3

Sample Output 1

4

There are four divisors of 3! =6: 1, 2, 3 and 6. Thus, the output should be 4.

Sample Input 2

6

Sample Output 2

30

Sample Input 3

1000

Sample Output 3

972926972

Solution in C (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <stdlib.h>

#define N 5000
#define M 200
#define ST_SIZE 5000*5
#define LEAF_BASE leaf_base
#define INF 5001
typedef long long int ll;

ll g[N][N];
int a[N], b[N+1][M];
ll st[ST_SIZE];
int leaf_base=1;
int num;

ll max(ll x, ll y){
	if(x >= y) return x;
	else return y;
}

void init_st(int n, int m){
	int i;
	while(leaf_base < n) leaf_base*=2;
	num = leaf_base--;
	for(i=0; i<m; i++) b[N+1][i] = -1;
	for(i=0; i<leaf_base*2+1; i++) st[i] = INF;
}

void sum(int n){
	int i, j;

	for(i=0; i<n; i++){
		for(j=1; j<n; j++){
			g[i][j] += g[i][j-1];
		}
	}
	for(j=0; j<n; j++){
		for(i=1; i<=j; i++){
			g[i][j] += g[i-1][j];
		}
	}
}

void update(int k, int x){
	int idx, i;
	
	idx = LEAF_BASE + k;
	st[idx] = k;
	while(1){
		idx = (idx-1)/2;
		if(b[st[idx]][x] <= b[k][x]){
			st[idx] = k;
		}
		if(idx == 0) break;
	}
}

int max_dv(int x, int y, int m){
	if(b[x][m] >= b[y][m]) return x;
	else return y;
}

int query(int x, int a, int b, int k, int l, int r){
	int lv, rv;
	
	if(r<=a || l>=b) return INF;

	if(a<=l && b>=r) return st[k];
	else{
		lv = query(x, a, b, k*2+1, l, (l+r)/2);
		rv = query(x, a, b, k*2+2, (l+r)/2, r);
	}
	return max_dv(lv, rv, x);
}

int calc_g(int x, int l, int r, int n){
	int opt;
	int i, j;
	if(l >=  r) return 0;
	opt = query(x, l, r, 0, 0, num);
	g[l][opt] += b[opt][x];
	if(opt+1 < N) g[opt+1][opt] -= b[opt][x];
	if(r < N) g[l][r] -= b[opt][x];
	if(opt+1 < N && r < N) g[opt+1][r] += b[opt][x];
	
	calc_g(x, l, opt, num);
	calc_g(x, opt+1, r, num);

	return 0;
}

int main (void){
	int n, m, tmp;
	int i, j, k;
	ll ret=0, dist;

	scanf("%d %d", &n, &m);
	init_st(n, m);
	a[n-1] = 0;
	for(i=0; i<n-1; i++) scanf("%d", &a[i]);
	for(i=0; i<n; i++){
		for(j=0; j<m; j++){
			scanf("%d", &b[i][j]);
		}
		b[INF][j] = -1;
	}
	for(i=0; i<m; i++){
		for(j=0; j<n; j++){
			update(j, i);
		}
		calc_g(i, 0, n, num);
	}
	sum(n);

	for(i=0; i<n; i++){
		dist = 0;
		for(j=i; j<n; j++){
			ret = max(ret, g[i][j]-dist);
			dist += a[j];
		}
	}

	printf("%lld\n", ret);
	
	
	return 0;
}