ICPC徐州網絡賽——M.Longest subsequence

大致題意:在第一個字符串str1中找一個最長的子序列,要求這個子序列的字典序嚴格大於第二個字符串。

題解上面說的是維護一下以當前位置的字符結尾的 滿足的子序列 的最長長度,感覺說起來好奇怪。反正不知道因爲什麼原因,在比賽的時候就是沒有想到這種寫法,但是看完題的第一眼,直覺告訴我應該用線段樹。所以二話不說上手寫一發,然後wa了。。最後手寫了幾組數據,把細節處理了就A了。主要是這兩組數據aaaaa aaa 和aaaaa aaaaa。處理出這兩種情況之後就A了。

最後,代碼:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+100;
char str1[maxn];
char str2[maxn];
int tree[maxn<<2];
int ans;
void push_up(int x,int tp)
{
    tree[x]=max(tree[tp],tree[tp+1]);
}
void build(int l,int r,int x)
{
    if(l==r)
    {
        tree[x]=str1[l]-'a';
        return ;
    }
    int tp=x<<1;
    int mid=l+r>>1;
    build(l,mid,tp);
    build(mid+1,r,tp+1);
    push_up(x,tp);
}
void query(int l,int r,int L,int x,int k)
{
    if(r<L||ans||tree[x]<k)
        return ;
    if(l==r)
    {
        ans=l;
        return ;
    }
    int tp=x<<1;
    int mid=l+r>>1;
    query(l,mid,L,tp,k);
    query(mid+1,r,L,tp+1,k);
}
int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    scanf("%s %s",str1+1,str2);
    build(1,n,1);
    int l=0;
    int Accepty=-1;
    for(int i=0;i<m;++i)
    {
        ans=0;
        query(1,n,l,1,str2[i]-'a'+1);
        if(ans)
        {
            Accepty=max(Accepty,n-ans+1+i);
        }
        ans=0;
        query(1,n,l,1,str2[i]-'a');
        if(ans)
        {
            l=ans+1;
            if(i==m-1&&ans!=n)
            {
                Accepty=max(Accepty,n-ans+1+i);
            }
        }
        else
            break;
    }
    cout<<Accepty<<endl;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章