您的位置:首页 > 产品设计 > UI/UE

[树状数组+DP]hdu3450 Counting Sequences

2015-08-27 11:25 405 查看
题意:

找出所有的美丽序列。美丽序列就是相邻的元素绝对值之差不超过d的序列。

分析:

dp[i]表示到i为止满足情况的种类数。

dp[i]=sum(dp[j] abs(a[j]-a[i])<=d);

当然这个数据量很大,直接按照方程的话复杂度为O(n*n). 所以要利用其他方式,树状数组。这里需要对元素离散化,因为d很大。刚开始想的时候以为二维的DP可以,但是存储空间不允许。后来一直不明白的问题是如何证明:

dp[i]=sum(dp[j] abs(a[j]-a[i])<=d);

假如 1 3 5 7 满足序列,那么美丽序列就有{1,3}{3,5}{5,7}{1,3,5}{3,5,7}{1,3,5,7} 分别为两个元素的情况,三个元素的情况,四个元素的情况。当然我们数的时候会这样想,但是计算的时候就不能这样想了。首先加入树状数组之前,先求出满足条件的种类数,那么这个数就要加入到这些合法的序列后面才合法,而这些合法的序列的由来又有很多种方式+1(只有自己),所以结果还是递推出来的。

[code]
#include<iostream>   
#include<stdio.h>  
#include<math.h>  
#include<utility>
#include <map>
#include<cstring>
#include<vector>
#include<deque>
#include<queue>
#include<stack>
#include<algorithm> 
#include<stdlib.h>  
#define read freopen("q.txt","r",stdin) 
#define LL long long 
const int maxn =100005;
const double inf=2000000000.0;
const int mod=9901;

using namespace std;
int c[maxn],a[maxn],hs[maxn];
int cnt,n;
int lowbit(int x)
{
    return x&(-x);
}
int getSum(int x)
{
    int sum=0;
    for(int i=x;i>0;i-=lowbit(i))
    {
        sum+=c[i];
        sum%=mod;
    }
    return sum; 
} 

void update(int x,int val)
{
    for(int i=x;i<=n;i+=lowbit(i))
    {
        c[i]+=val;
    }
}

int low(int x)
{
    int l=1,r=cnt;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(hs[mid]<x)l=mid+1;
        else r=mid-1; 
    }
    return r+1;
}
int up(int x)
{
    int l=1,r=cnt;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(hs[mid]<=x)l=mid+1;
        else r=mid-1;
    }
    return l-1;
}
int main()
{
    int d,i,j;
    while(~scanf("%d%d",&n,&d))
    {
        memset(c,0,sizeof(c));
        for(i=1;i<=n;i++)
        {
            scanf("%d",a+i);
            hs[i]=a[i];
        }
        sort(hs+1,hs+n+1);
        cnt=1;
        for(i=2;i<=n;i++)if(hs[i]!=hs[cnt])hs[++cnt]=hs[i];
        int sum=0;
        for(i=1;i<=n;i++)
        {
            int x=low(a[i]-d),y=up(a[i]+d),z=low(a[i]);
            int tmp=getSum(y)-getSum(x-1);
            tmp+=mod;
            tmp%=mod;
        /////////////// cout<<"TTTTmp = "<<tmp<<endl;
            sum=(sum+tmp)%mod;
            update(z,tmp+1);
        //  cout<<"sum = "<<sum<<endl;
        }
        cout<<sum<<endl;

    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: