Counting Sequences

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/65536 K (Java/Others)
Total Submission(s): 1158    Accepted Submission(s): 397


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
 

Sample Output
4
 代码:
#include<stdio.h>
#include <algorithm>
using namespace std;
#define  N  100010
#define MOD  9901
#define lowbit(x) (x&(-x))
int cnt;
int p[N];
int hash[N];
int a[N];
int b[N];
int n,d;
int find1 ( int x ) //二分找 <=x的第一个数;
{        
    int l= 1;
 int r= cnt;
 int m= (l+r) /2;
 int rec= m;
    while ( l<=r )
 {
           if ( hash[m] <= x )
     {
                l= m+ 1;
    rec= m;
           }
     else
     {
                r= m - 1;
           }
           m = ( l+r ) / 2;
    }
    return rec;
}
int find2 ( int x )// 二分找 >= x的第一个数;
{        
    int l= 1;
 int r= cnt;
  int m = ( l+r) /2 ;
  int rec = m;
    while (l<=r)
 {
           if ( hash[m] < x )
     {
                l = m+ 1;
           }
     else
     {
                r = m - 1; rec = m;
           }
           m = ( l+r)/2;
    }
    return rec;
}
int quy ( int x )// 查询 ;
{                 
    int sum = 0;
    while ( x > 0 )
 {
           sum += p[x];
     x -= lowbit ( x );
    }
    return sum ;
}
void modify ( int a, int b )// 修改;
{     
     while ( a<= cnt )
  {
            p[a] +=b;
   a+= lowbit ( a );
     }    
}
int main ()
{
    while (scanf("%d%d",&n,&d)!=-1)
 {
           for ( int i = 0; i < n; ++ i ){
                scanf("%d",&a[i]);
     b[i] = a[i]; 
           }
           memset ( p, 0, sizeof(p) );
           sort ( a, a+n);
           hash[1] = a[0];
      cnt = 1;
           for ( int i = 1; i < n; ++ i )// 数据离散化;
     {              
                if ( a[i] != a[i-1] )
    hash[++cnt] = a[i];
           }
           for ( int i = 0; i < n; ++ i )
     {
                int pos = find1 ( b[i] );     // 找当前元素的 hash下标;          
                int pre = find1 ( b[i] + d ); // 找 <=b[i] + d的第一个数;        
                int tail = find2 ( b[i] - d ); // 找 >=b[i]-d的第一个数;     
                int val = quy ( pre ) - quy ( tail - 1 ) + 1;  // 区间[b[i]-d,b[i]+d]的元素个数+新增的一个元素(本身);
                modify ( pos, val%MOD );
           }
           printf( "%d\n",( quy ( cnt ) - n  ) % MOD);  //以一个元素的[elem-d,elem+d]计算,题目要求k>=2,减掉 n个;
    }
    return 0;
}