Codechef 12.12 DIFTRIP Trie树+后缀自动机+STL

 

BZOJ4236: JOIOJI

题解:

考虑任意一个串都是两个前缀之差.

如果这个串要满足$num(J)=num(O)=num(I)$,那么两个前缀$num(J),num(O),num(I)$的相对大小关系必须是相同的.

我们对于每个前缀记下$num(J)-num(O),num(J)-num(I)$,然后利用map随便搞搞就行了.

代码:

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
 
typedef pair<int,int> pii;
#define mp make_pair
 
#define N 200010
char s[N];
 
map<pii,int>M;
int main(){
    int n;
    scanf("%d",&n);
    scanf("%s",s+1);
     
    M[mp(0,0)]=0;
    int J=0,O=0,I=0,ans=0;
    for(int i=1;i<=n;++i){
        if(s[i]=='J')
            ++J;
        if(s[i]=='O')
            ++O;
        if(s[i]=='I')
            ++I;
        if(M.count(mp(J-O,J-I)))
            ans=max(ans,i-M[mp(J-O,J-I)]);
        else
            M[mp(J-O,J-I)]=i;
    }
    cout<<ans<<endl;
    return 0;
}

BZOJ2882:工艺 STL+后缀自动机

思路:这大概也算是后缀自动机裸题了吧.

虽然最小表示法最靠谱,不过我还是懒,于是用map水了一发.好方便啊~`

注意数据范围有一些不靠谱,详情见代码= =

#include<cstdio>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
 
#define N 500010
map<int,int>tranc[N<<1];int pa[N<<1],len[N<<1],cnt,root,last;
inline int newnode(int l){
    len[++cnt]=l;return cnt;
}
inline void init(){
    root=last=newnode(0);
}
 
int a[N<<1];
int main(){
    int n;scanf("%d",&n);register int i,j;for(i=1;i<=n;++i)scanf("%d",&a[i]),a[i+n]=a[i];
    int p,np,q,nq,y;
    for(init(),i=1;i<=n*2;++i){
        np=newnode(len[last]+1);
        for(p=last,y=a[i];tranc[p].find(y)==tranc[p].end();p=pa[p])tranc[p][y]=np;
        if(!p)pa[np]=root;
        else{
            q=tranc[p][y];
            if(len[q]==len[p]+1)pa[np]=q;
            else{
                nq=newnode(len[p]+1),pa[nq]=pa[q],pa[q]=pa[np]=nq;
                tranc[nq]=tranc[q];
                for(;p&&tranc[p].find(y)!=tranc[p].end()&&tranc[p][y]==q;p=pa[p])tranc[p][y]=nq;
            }
        }last=np;
    }
    map<int,int>::iterator it;
    for(i=1,p=root;i<=n;++i){
        if(i>1)putchar(' ');
        it=tranc[p].begin();
        printf("%d",it->first);
        p=tranc[p][it->first];
    }
 
    return 0;
}