HDU6701:Make Rounddog Happy(啟發式分治)


題意:給定數組a[],求區間個數,滿足區間的數各不同,而且滿足maxval-len<=K;

思路:一看就可以分治做,對於當前的區間,從max位置分治。 對於這一層,需要高效的統計答案,那么對短的一邊開始統計。

(這個過程很像啟發式的逆過程,所以叫做啟發式分治

1,對於數不同,這個可以預處理前綴和后綴的最大區間長度A[],B[]。

2,st表得到區間最大值位置,然后就可以搞了。

如果是第一次遇到,可以參考同一類的題目:

2019牛客暑期多校訓練營(第三場)G: Removing Stones(啟發式分治)

Non-boring sequences(啟發式分治)

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
int a[maxn],st[maxn][21],lg[maxn],K,N; ll ans;
int A[maxn],B[maxn],vis[maxn];
int get(int L,int R)
{
    int k=lg[R-L+1];
    return a[st[L][k]]>=a[st[R-(1<<k)+1][k]]?st[L][k]:st[R-(1<<k)+1][k];
}
void solve(int L,int R)
{
    if(L>R) return ;
    int pos=get(L,R);
    if(pos-L<R-pos){
        rep(i,L,pos){
            int t=a[pos]-K,lR=i+t-1;
            int fcy=min(R,B[i]);
            lR=max(lR,pos);
            if(lR>fcy) continue;
            ans+=fcy-lR+1;
        }
    }
    else {
        rep(i,pos,R){
            int t=a[pos]-K,rL=i-t+1;
            int fcy=max(L,A[i]);
            rL=min(rL,pos);
            if(rL<fcy) continue;
            ans+=rL-fcy+1;
        }
    }
    solve(L,pos-1); solve(pos+1,R);
}
int main()
{
    int T;
    lg[0]=-1; rep(i,1,maxn-1) lg[i]=lg[i>>1]+1;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&N,&K); ans=0;
        rep(i,1,N) scanf("%d",&a[i]);
        rep(i,1,N) st[i][0]=i;
        rep(i,1,20) {
            rep(j,1,N+1-(1<<i))
             st[j][i]=a[st[j][i-1]]>=a[st[j+(1<<(i-1))][i-1]]?st[j][i-1]:st[j+(1<<(i-1))][i-1];
        }

        rep(i,1,N) vis[i]=0; A[1]=1; vis[a[1]]=1;
        rep(i,2,N){
             if(vis[a[i]])  A[i]=max(A[i-1],vis[a[i]]+1);
             else A[i]=A[i-1];
             vis[a[i]]=i;
        }
        rep(i,1,N) vis[i]=0; B[N]=N; vis[a[N]]=N;
        for(int i=N-1;i>=1;i--){
            if(vis[a[i]]) B[i]=min(B[i+1],vis[a[i]]-1);
            else B[i]=B[i+1];
            vis[a[i]]=i;
        }
        solve(1,N);
        printf("%lld\n",ans);
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM