CF1200E Compress Words(KMP)
CF1200E Compress Words(KMP)
分析
每次让答案和新串匹配前后缀即可。
细节
- \(n\le 10^5\),但是字符串长度是 \(\le 10^6\) 的。
- 最大相同的前缀最多就 \(O(len)\) 个(\(len\) 是新串长度),不用每次把答案字符串扫完。
Code
#include<bits/stdc++.h>
#define sd std::
//#define int long long
#define il inline
#define db double
#define ldb long double
#define F(i,a,b) for(int i=(a);i<=(b);i++)
#define f(i,a,b) for(int i=(a);i>=(b);i--)
#define MIN(x,y) (x<y?x:y)
#define MAX(x,y) (x>y?x:y)
#define me(x,y) memset(x,y,sizeof x)
#define pii sd pair<int,int>
#define X first
#define Y second
#define kg putchar(' ')
#define Fr(a) for(auto it:a)
#define dbg(x) sd cout<<#x<<": "<<x<<sd endl
il int read(){int w=1,c=0;char ch=getchar();for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;for(;ch>='0'&&ch<='9';ch=getchar()) c=(c<<3)+(c<<1)+ch-48;return w*c;}
void printt(int x){if(x>9) printt(x/10);putchar(x%10+48);}
il void print(int x){if(x<0) putchar('-'),printt(-x);else printt(x);}
il void put(int x){print(x);putchar('\n');}
il void printk(int x){print(x);kg;}
const int N=1e6+10;
int n,p[N];
sd string ans;
char s[N];
il void solve()
{
scanf("%s",s+1);
n=strlen(s+1);
if(ans=="")
{
F(i,1,n) ans+=s[i];
return;
}
int j=p[1]=0;
F(i,2,n)
{
while(j>0&&s[j+1]!=s[i]) j=p[j];
if(s[j+1]==s[i]) j++;
p[i]=j;
}
j=0;
int mi=MIN(ans.size(),n);
//ans:0~ans.size()-1
F(i,ans.size()-mi,ans.size()-1)
{
while(j>0&&ans[i]!=s[j+1]) j=p[j];
if(s[j+1]==ans[i]) j++;
}
F(i,j+1,n) ans+=s[i];
}
int main()
{
ans="";
int T=1;
T=read();
while(T--) solve();
sd cout<<ans;
return 0;
}

浙公网安备 33010602011771号