こんにゃくの退屈の1

?非常に単純な練習の手の話題
Https://loj.ac/problem/10121#submit_code
効果の対象には:
繰り返し完璧なシーケンス区間を求めた。(個々の数字の連続したシーケンスのための完璧なシーケンスとして定義が異なります)
、最も多くの間隔を求めて長い(変更なし)完璧なシーケンス
解析:
静的クエリ:最後の配列は、ほとんどを行うには?DPアレイ
(動的チームは、それが希望MO推定照会)
最終[[I]は、数A [i]が最初に出現する位置を示して
完全の最長シーケンスのi番目のビットの終わりに開始を表す[I] DPを最大位置
を有する:DPは、[I] = MAX( DP [I-1]、最後に[I] + 1)!!!!!!!!!!!!!!!!!!!! この配列はキーである!!!!!!!!!!!!!!! DP
と最後のクエリテーブルを予め-ST(I-DPは、[I] +1 ) 、各シーケンスの長さである
単調最後のアレイが増加するのでので、前の段落の半周期で間隔の範囲内にない解決することができる
手の半分は、ハードの境界を制御するようにされていないことができない
wzxbelieverによってコード

#include<bits/stdc++.h>
#define ll long long
#define lowbit(x) x&(-x)
#define il inline
#define ri register int
using namespace std;
const int maxn=2e5+5;
const int maxx=1e6;
int lg[maxn],last[(maxx<<1)+5],st[maxn][20],s[maxn],f[maxn];
int n,m;
il void init(){
    lg[0]=-1;
    for(ri i=1;i<=n;i++)lg[i]=lg[i>>1]+1;
    for(ri j=1;(1<<j)<=n;j++)
    for(ri i=1;i+(1<<j)-1<=n;i++)
    st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
    return;
} 
il int askmax(int L,int R){
    if(L>R)return 0;
    int k=lg[R-L+1];
    return max(st[L][k],st[R-(1<<k)+1][k]);
}
int main(){ 
    scanf("%d%d",&n,&m);
    for(ri i=1,x;i<=n;i++){
        scanf("%d",&x);
    s[i]=max(s[i-1],last[x+maxx]+1);
    f[i]=i-s[i]+1;
    st[i][0]=f[i];
    last[x+maxx]=i;
    }
    init();
    for(ri i=1,L,R;i<=m;i++){
        scanf("%d%d",&L,&R);L++,R++;
        int pos=lower_bound(s+1+L,s+1+R,L)-s-1;
        //cout<<"pos="<<pos<<endl;
       printf("%d\n",max(pos-L+1,askmax(pos+1,R)));
    } 
   return 0;
}

おすすめ

転載: www.cnblogs.com/wzxbeliever/p/12198953.html
おすすめ