hdu3450Counting Sequences DP+樹狀陣列
Counting SequencesTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/65536 K (Java/Others)Total Submission(s): 3012 Accepted Submission(s): 1067 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
Source 2010 ACM-ICPC Multi-University Training Contest(2)——Host by BUPT
Recommend We have carefully selected several similar problems for you: 1541 1394 2838 3030 2227
|
#include<stdio.h>
#include<string>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
const int MAXN=200000+5;//最大元素個數
int d,n;//元素個數
ll c[MAXN];
int a[MAXN],b[MAXN];//c[i]==A[i]+A[i-1]+...+A[i-lowbit(i)+1]
//返回i的二進位制最右邊1的值
int lowbit(int i)
{
return i&(-i);
}
//返回A[1]+...A[i]的和
ll sum(int x){
ll sum = 0;
while(x){
sum += c[x];
x -= lowbit(x);
}
return sum;
}
//令A[i] += val
void add(int x, ll val){
while(x <= n){
c[x] += val;
x += lowbit(x);
}
}
const int mod=9901;
int main()
{
while(scanf("%d%d",&n,&d)!=-1)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(a+1,a+n+1);
int len=unique(a+1,a+n+1)-a-1;
memset(c,0,sizeof(c));
int ans=0;
for(int i=1;i<=n;i++)
{
int pos1=upper_bound(a+1,a+1+len,b[i]+d)-(a+1); ///右界
int pos2=lower_bound(a+1,a+1+len,b[i]-d)-(a+1);///左界
int pos=lower_bound(a+1,a+1+len,b[i])-a; ///本身位置
ll sum1=((sum(pos1)-sum(pos2))%mod+mod)%mod; ///查詢以a[i]為結尾的完美序列
ans=(ans+sum1)%mod;
add(pos,sum1+1);
}
cout<<ans<<endl;
}
return 0;
}