4516: [Sdoi2016]生成魔咒
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1460 Solved: 835
[Submit][Status][Discuss]
Description
Input
Output
输出 n 行,每行一个数。第 i 行的数表示第 i 次操作后 S 的生成魔咒数量
Sample Input
1 2 3 3 3 1 2
Sample Output
3
6
9
12
17
22
HINT
Source
/************************************************************** Problem: 4516 User: JYYHH Language: C++ Result: Accepted Time:792 ms Memory:14936 kb ****************************************************************/ #include<bits/stdc++.h> #define ll long long #define maxn 200005 using namespace std; map<int,int> ch[maxn]; int n,m,cnt=1,pre=1,k; int l[maxn],f[maxn]; ll ans=0; inline void ins(int x){ int p=pre,np=++cnt; pre=np,l[np]=l[p]+1; for(;p&&!ch[p].count(x);p=f[p]) ch[p][x]=np; if(!p) f[np]=1; else{ int q=ch[p][x]; if(l[q]==l[p]+1) f[np]=q; else{ int nq=++cnt; l[nq]=l[p]+1; ch[nq]=ch[q]; ans-=(ll)l[q]-l[f[q]]; f[nq]=f[q]; f[q]=f[np]=nq; ans+=(ll)l[q]-l[f[q]]; ans+=(ll)l[nq]-l[f[nq]]; for(;ch[p][x]==q;p=f[p]) ch[p][x]=nq; } } ans+=(ll)l[np]-l[f[np]]; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&k); ins(k); printf("%lld\n",ans); } return 0; }