码迷,mamicode.com
首页 > 其他好文 > 详细

HDU2836 Traversal

时间:2016-09-22 21:24:38      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:

题解:

dp+树状数组优化

跟hdu2227差不多,只不过改变了一下范围。更改一下sum的方式即可

但是这题的a[i]范围比较大。

在用树状数组时,一种是直接使用map,另一种是使用hash+二分

代码:

map优化 1060ms

#include<bits/stdc++.h>
using namespace std;
#define LL long long 
const int N=100010;
const int M=100000100;
const int mod=9901;

int n,h,Min,Max;
int a[N],dp[N];
map<int,int> c;

int lowbit(int x){return x&-x;}

void add(int x,int v){
    while(x<M){
        c[x]+=v;
        c[x]%=mod;
        x+=lowbit(x);
    }
}

int sum(int x){
    int cnt=0;
    while(x){
        cnt+=c[x];
        cnt%=mod;
        x-=lowbit(x);
    }
    return cnt;
}

int main(){
    while(~scanf("%d%d",&n,&h)){
        c.clear();
        for(int i=1;i<=n;i++){
             scanf("%d",&a[i]);
             Min=max(a[i]-h,1);
             Max=min(a[i]+h,M-5);
             dp[i]=sum(Max)-sum(Min-1);
             add(a[i],dp[i]+1);
        }
        printf("%d\n",((sum(M)-n)%mod+mod)%mod);
    }
    return 0;
}

 

hash+二分 156ms

#include<bits/stdc++.h>
using namespace std;
#define LL long long 
const int N=100010;
const int M=100000100;
const int mod=9901;

int a[N],t[N],c[N];
int n,h,tot;

int lowbit(int x){return x&-x;}

void add(int x,int v){
    while(x<=tot){
        c[x]+=v;
        c[x]%=mod;
        x+=lowbit(x);
    }
}

int sum(int x){
    int cnt=0;
    while(x){
        cnt+=c[x];
        cnt%=mod;
        x-=lowbit(x);
    }
    return cnt;
}

int Bin(int v){
    int l=1,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 lBin(int v){
    int l=1,r=tot,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 rBin(int v){
    int l=1,r=tot,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 main(){
    while(~scanf("%d%d",&n,&h)){
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            t[i]=a[i];
        }
        sort(t+1,t+n+1);
        tot=0;
        for(int i=1;i<=n;i++){
            if(i==1||t[i]!=t[i-1]){
                t[++tot]=t[i];//去掉重复元素 
                c[tot]=0;
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            int nidx=Bin(a[i]);
            int l=lBin(a[i]-h);//大于等于a[i]-h的最小值位置 
            int r=rBin(a[i]+h);//小于等于a[i]+h的最大值位置 
            int val=(sum(r)-sum(l-1)+mod)%mod;
            ans=(ans+val+1)%mod;
            add(nidx,val+1);
        }
        printf("%d\n",((ans-n)%mod+mod)%mod);
    }
    return 0;
}

 

HDU2836 Traversal

标签:

原文地址:http://www.cnblogs.com/byene/p/5897747.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!