http://www.lydsy.com/JudgeOnline/problem.php?id=2013
最初看这个题的时候,以为神题不可做,然后去找yzjc。。然后做法过于简单了(' ' )
先排个序。假设我们已经将前i个砖块有一个合法的方案,那么加入第i + 1个砖块的时候可加入的位置都是一定的,都为在1 ~ i 中 > l[i +1] - D 的砖块的个数,因为插在中间的时候由于保证了所有已经加入的砖块的长度都小于i + 1块,所以只和上一块有关,所以只要满足上面那个式子就可以了。所以问题转化成将每一个位置前缀满足上面式子的个数乘起来就是答案
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long ll; const ll maxn = 710000; const ll mod = (ll)1e9 + 9ll; ll ll_get() { ll x = 0; char c = (char)getchar(); bool f = 0; while(!isdigit(c)) { if(c == '-') f = 1; c = (char)getchar(); } while(isdigit(c)) { x = x * 10 + (ll)(c - '0'); c = (char)getchar(); } if(f) x = -x; return x; } ll n, a[maxn], d; void read() { n = ll_get(); d = ll_get(); for(ll i = 1; i <= n; ++ i) a[i] = ll_get(); } ll ans = 1; void sov() { ll l = 1; sort(a + 1, a + 1 + n); for(ll i = 2; i <= n; ++ i) { while(a[i] - a[l] > d) ++ l; ans = ans * (i - l + 1) % mod; } printf("%lld\n", ans); } int main() { //freopen("test.in", "r", stdin); read(), sov(); return 0; }