每條邊表示要加的字元,每個節點代表從根開始走形成的字串。
h
he
hel
hell
hello
k
ke
key
ken
+h
+e
+l
+l
+o
+k
+e
+y
+n
假設今天要加入 "bee", "yee", "yes", "yuhung", "zap", "zaps"
b
be
bee
y
ye
yee
yes
yu
yuh
yuhu
yuhun
yuhung
z
za
zap
zaps
+b
+e
+e
+y
+e
+e
+s
+u
+h
+u
+n
+g
+z
+a
+p
+s
struct Node {
vector<int> c;
Node(): c(26, -1) {}
int &operator()(char nxt) {
return c[nxt - 'a'];
}
};
vector<Node> trie;
int add(string &str, int now, int id) {
// cout<<now<<"now"<<id<<"id\n";
if (id == -1) {
id = tmp++;
}
if (now == str.size())
return id;
trie[id](str[now]) = add(str, now + 1, trie[id](str[now]));
return id;
}
int search(string &str, int now, int id) {
if (now == str.size())
return now;
char c = str[now];
if (trie[id](c) != -1) {
return search(str,now+1,trie[id](c));
}
return now+1;
}//Author: Woody
#include <bits/stdc++.h>
#define int long long
#define mp make_pair
#define eb emplace_back
#define rep(n) for(int i=0;i<n;i++)
#define rep2(n) for(int j=0;j<n;j++)
#define F first
#define S second
#define all(v) v.begin(),v.end()
#define SZ(x) (int)(x.size())
#define lowbit(x) (x&-x)
#define SETIO(s) ifstream cin(s+".in");ofstream cout(s+".out");
#define quick ios::sync_with_stdio(0);cin.tie(0);
using namespace std;
typedef pair<int, int> pii;
template <class t1, class t2>
inline const pair<t1, t2> operator + (const pair<t1, t2> &p1, const pair<t1, t2> &p2) {
return pair<t1, t2>(p1.F + p2.F, p1.S + p2.S);
}
template <class t1, class t2>
inline const pair<t1, t2> operator - (const pair<t1, t2> &p1, const pair<t1, t2> &p2) {
return pair<t1, t2>(p1.F - p2.F, p1.S - p2.S);
}
const int INF = 1e18;
const int N = 1e5 + 7;
const int D = 31;
string s[N];
string bin(int num) {
string S;
while (num > 0) {
if (num & 1)
S += "1";
else
S += "0";
num >>= 1;
}
S += string(D - S.size(), '0');
reverse(all(S));
return S;
}
int tmp = 1;
struct Node {
vector<int> c;
Node(): c(2, -1) {}
int &operator()(char nxt) {
return c[nxt - '0'];
}
};
vector<Node> trie;
int add(string &str, int now, int id) {
// cout<<now<<"now"<<id<<"id\n";
if (id == -1) {
id = tmp++;
}
if (now == str.size())
return id;
trie[id](str[now]) = add(str, now + 1, trie[id](str[now]));
return id;
}
int search(string &str, int now, int id) {
if (now == str.size())
return 0;
char c = '1' - str[now] + '0';
if (trie[id](c) != -1) {
return (1 << (D - now - 1)) + search(str, now + 1, trie[id](c));
}
return search(str, now + 1, trie[id](str[now]));
}
signed main() {
quick
trie.resize(2e6 + 7);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int a;
cin >> a;
s[i] = bin(a);
// cout<<s[i].size()<<"l\n";
add(s[i], 0, 0);
}//return 0;
int ans = 0;
for (int i = 0; i < n; i++) {
int P = search(s[i], 0, 0);
// cout<<ans<<","<<P<<"P\n";
ans = max(ans, P);
}
cout << ans << "\n";
return 0;
}int KMP(string a,string b){
vector<int> f=buildf(b);
int ans=0;
int n=sz(a);
int m=sz(b);
int pos=0;
rep(i,0,n-1){
while(a[i]!=b[pos]&&pos){
pos=f[pos-1];
}
if(a[i]==b[pos]) pos++;
if(pos>=m){
ans++;
pos=f[pos-1];
}
}
return ans;
}vector<int> buildf(const string&p){
int n=sz(p);
vector<int> f(n);
int pos=0;
rep(i,1,n-1){
while(p[i]!=p[pos]&&pos){
pos=f[pos-1];
}
if(p[i]==p[pos]) pos++;
f[i]=pos;
}
return f;
}int KMP(string a,string b){
vector<int> f=buildf(b);
int ans=0;
int n=sz(a);
int m=sz(b);
int pos=0;
rep(i,0,n-1){
while(a[i]!=b[pos]&&pos){
pos=f[pos-1];
}
if(a[i]==b[pos]) pos++;
if(pos>=m){
ans++;
pos=f[pos-1];
}
}
return ans;
}字串匹配的唯一選擇
\(H_{l\sim r}=H_r-H_l\cdot p^{r-l}\)
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx,popcnt,sse4,abm")
#include<bits/stdc++.h>
#define int long long
#define quick ios::sync_with_stdio(0);cin.tie(0);
#define rep(x,a,b) for(int x=a;x<=b;x++)
#define repd(x,a,b) for(int x=a;x>=b;x--)
#define lowbit(x) (x&-x)
#define sz(x) (int)(x.size())
#define F first
#define S second
#define all(x) x.begin(),x.end()
#define mp make_pair
#define eb emplace_back
using namespace std;
typedef complex<int> P;
#define X real()
#define Y imag()
typedef pair<int,int> pii;
void debug(){
cout<<"\n";
}
template <class T,class ... U >
void debug(T a, U ... b){
cout<<a<<" ",debug(b...);
}
const int N=1e6+7;
const int INF=1e18;
pii operator + (pii a,pii b){
return mp(a.F+b.F,a.S+b.S);
}
pii operator + (pii a, int b){
return mp(a.F+b,a.S+b);
}
pii operator - (pii a,pii b){
return mp(a.F-b.F,a.S-b.S);
}
pii operator * (pii a,int k){
return mp(a.F*k,a.S*k);
}
pii operator * (pii a,pii b){
return mp(a.F*b.F,a.S*b.S);
}
pii operator % (pii x,pii y){
return mp(x.F%y.F,x.S%y.S);
}
bool operator == (pii a,pii b){
return a.F==b.F&&a.S==b.S;
}
const pii Mod={1234567891,998244353};
int p;
pii pw[N];
pii pref[N];
pii suff[N];
pii q(int l,int r,bool pf){
if(pf){
return (pref[r]-pref[l-1]*pw[r-l+1]%Mod+Mod)%Mod;
}
return (suff[l]-suff[r+1]*pw[r-l+1]%Mod+Mod)%Mod;
}
bool ok(int posl,int pos,int pos2,int posr,int n){
if(posl<=0||posr>n) {return false;}
return q(posl,pos,true)==q(pos2,posr,false);
}
bool ok(int ln,int pos,int pos2,int n){
return ok(pos-ln,pos,pos2,pos2+ln,n);
}
int qry(int pos,int pos2,int n){
int l=0;
int r=n+1;
while(l+1<r){
int mid=(l+r)>>1;
if(ok(mid,pos,pos2,n)) l=mid;
else r=mid;
}
return l;
}
signed main(){
quick
string s;
cin>>s;
int n=sz(s);
s=' '+s;
mt19937 rand;
p=rand()%17+29;
pw[0]=mp(1,1);
rep(i,1,n){
pw[i]=pw[i-1]*p%Mod;
}
rep(i,1,n){
pref[i]=(pref[i-1]*p+(s[i]-'a'+1))%Mod;
}
repd(i,n,1){
suff[i]=(suff[i+1]*p+(s[i]-'a'+1))%Mod;
}
int L,R;
L=R=0;
int ans=0;
rep(i,1,n){
int l1=qry(i,i,n);
if(l1*2+1>ans){
ans=l1*2+1;
L=i-l1;
R=i+l1;
}
if(i+1<=n&&s[i]==s[i+1]){
int l2=qry(i,i+1,n);
if(l2*2+2>ans){
ans=l2*2+2;
L=i-l2;
R=i+l2+1;
}
}
}
rep(i,L,R) cout<<s[i];cout<<"\n";
return 0;
}