Counting Sequences
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/65536 K (Java/Others)
Total Submission(s): 786 Accepted Submission(s): 262
Problem Description
For a set of sequences of integers{a1,a2,a3,...an}, we define a sequence{ai1,ai2,ai3...aik}in which 1<=i1<i2<i3<...<ik<=n, as the sub-sequence of {a1,a2,a3,...an}. It is quite obvious that a sequence with the length n has 2^n sub-sequences. And for a sub-sequence{ai1,ai2,ai3...aik},if it matches the following qualities: k >= 2, and the neighboring 2 elements have the difference not larger than d, it will be defined as a Perfect Sub-sequence. Now given an integer sequence, calculate the number of its perfect sub-sequence.
Input
Multiple test cases The first line will contain 2 integers n, d(2<=n<=100000,1<=d=<=10000000) The second line n integers, representing the suquence
Output
The number of Perfect Sub-sequences mod 9901
Sample Input
4 2
1 3 7 5
1 3 7 5
Sample Output
4
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 100010
#define mod 9901
int n;
int val[maxn], t[maxn], c[maxn];
int tot;
int lowbit(int x) {
return x & (-x);
}
void add(int pos, int v) {
while(pos <= tot) {
c[pos] += v;
if(c[pos] >= mod )
c[pos] %= mod;
pos += lowbit(pos);
}
}
int sum(int pos) {
int s = 0;
while(pos >= 1) {
s += c[pos];
if(s >= mod )
s %= mod;
pos -= lowbit(pos);
}
return s;
}
int Bin(int v) {
int l = 1;
int r = tot;
while(l <= r) {
int m = (l + r) >> 1;
if(v == t[m])
return m;
if(v > t[m])
l = m + 1;
else
r = m - 1;
}
}
// 找到最小的大于等于它的数
int BThan(int v) {
int l = 1;
int r = tot;
int ans = 1;
while(l <= r) {
int m = (l + r) >> 1;
if(t[m] >= v) {
r = m - 1;
ans = m;
}else
l = m + 1;
}
return ans;
}
// 找到最大的小于等于它的数
int LThan(int v) {
int l = 1;
int r = tot;
int ans = tot;
while(l <= r) {
int m = (l + r) >> 1;
if(t[m] <= v) {
l = m + 1;
ans = m;
}else
r = m - 1;
}
return ans;
}
int H;
int main() {
int i;
while(scanf("%d %d", &n, &H) != EOF) {
for(i = 0; i < n; i++) {
scanf("%d", &val[i]);
t[i+1] = val[i];
}
tot = 0;
sort(t+1, t+1+n);
for(i = 1; i <= n; i++) {
if(i==1 || t[i] != t[i-1]) {
t[++tot] = t[i];
c[tot] = 0;
}
}
int ans = 0;
for(i = 0; i < n; i++) {
int nidx = Bin(val[i]);
int l = BThan(val[i] - H);
int r = LThan(val[i] + H);
int preVal = (sum(r) - sum(l-1)) % mod;
if(preVal < 0)
preVal += mod;
ans += preVal + 1; if(ans >= mod) ans %= mod;
add(nidx, preVal + 1);
}
printf("%d\n", ((ans - n) % mod + mod) % mod);
}
return 0;
}