BZOJ4236: JOIOJI
Aug 18, 2015 08:11:53 PM
题解:
考虑任意一个串都是两个前缀之差.
如果这个串要满足$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+后缀自动机
Feb 02, 2015 03:04:02 PM
思路:这大概也算是后缀自动机裸题了吧.
虽然最小表示法最靠谱,不过我还是懒,于是用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; }