字符串
目录
P3375 【模板】KMP字符串匹配(看毛片):
#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
#define mp(a,b) make_pair(a,b)
using namespace std;
int nex[500005];
string a,b;
void cl(string x)
{
nex[0]=-1;
int k=-1;
for1(i,1,x.size()-1)
{
while(x[k+1]!=x[i]&&k>-1) k=nex[k];
if(x[k+1]==x[i]) k++;
nex[i]=k;
}
return ;
}
int main()
{
cin>>a>>b;
cl(b);
int k=-1;
for1(i,0,a.size()-1)
{
while(b[k+1]!=a[i]&&k>-1) k=nex[k];
if(b[k+1]==a[i]) k++;
if(k==b.size()-1) printf("%d\n",i-b.size()+2);
}
for1(i,0,b.size()-1)
printf("%d ",nex[i]+1);
return 0;
}
P3370 【模板】字符串哈希:
#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
#define mp(a,b) make_pair(a,b)
using namespace std;
typedef unsigned long long ull;
ull base=233;
ull a[10010];
string s;
long long n,ans=1;
ull mod=1e18+3;
ull hashs(string s)
{
int len=s.size();
ull ans=0;
for (int i=0;i<len;i++)
{
ans=(ans*base)%mod;
ans=(ans+(ull)s[i])%mod;
}
return ans;
}
main()
{
scanf("%d",&n);
for1(i,1,n)
{
cin>>s;
a[i]=hashs(s);
}
sort(a+1,a+n+1);
for1(i,2,n)
if(a[i]!=a[i-1])
ans++;
printf("%d\n",ans);
}
字符串哈希2 poj2774 Long Long Message
每用一次我都要吐槽,poj真的难用
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define ull unsigned long long
#define for1(i,a,b) for(register int i = a;i<=b;i++)
using namespace std;
const int N = 1e5 + 10;
ull h1[N], h2[N], quan[N];
char s1[N], s2[N];
int base = 13331, len1, len2;
ull cl(ull *h, int l, int r)
{
return h[r] - h[l - 1] * quan[r - l + 1];
}
bool check(int len)
{
vector<ull> hash;
for1(i,len,len1)
{
ull ji = cl(h1, i - len + 1, i);
hash.push_back(ji);
}
sort(hash.begin(), hash.end());
for1(i, len, len2)
{
ull ji = cl(h2, i - len + 1, i);
if(binary_search(hash.begin(), hash.end(), ji))
return true;
}
return false;
}
int main()
{
cin >> s1 + 1 >> s2 + 1;
len1 = strlen(s1 + 1);
len2 = strlen(s2 + 1);
h1[0] = h2[0] = 0;
quan[0] = 1;
for1(i,1,N-1)
quan[i] = quan[i - 1] * base;
for1(i,1,len1)
h1[i] = h1[i - 1] * base + s1[i];
for1(i,1,len2)
h2[i] = h2[i - 1] * base + s2[i];
int len = min(len1, len2);
int l = 1, r = min(len1, len2);
int mid, ans = 0;
while(l <= r)
{
mid = (l + r) / 2;
if(check(mid))
{
ans = mid;
l = mid + 1;
}
else
{
r = mid - 1;
}
}
cout<<ans;
return 0;
}
Trie树 P8306 【模板】字典树
#include<bits/stdc++.h>
#define ll long long
#define for1(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
const int maxn = 3e6 + 5;
struct Point{
int son[80];
int fa;
int ans;
};
int mp[maxn];
struct Tree{
Point s[maxn << 1];
int cnt ;
Tree(){cnt = 0;}
void Clear(int x)
{
memset(s[x].son,0,sizeof(s[x].son));
s[x].ans = 0;
s[x].fa = 0;
}
void Insert(string x)
{
int now = 0;
int w;
for1(i,1,x.size()- 1)
{
if(s[now].son[mp[x[i]]] == 0)
s[now].son[mp[x[i]]] = ++cnt;
s[s[now].son[mp[x[i]]]].fa = now;
now = s[now].son[mp[x[i]]];
}
s[now].ans++;
while(now != 0)
{
s[s[now].fa].ans ++;
now = s[now].fa;
}
return ;
}
int Query(string x)
{
int now = 0;
for1(i,1,x.size()- 1)
{
if(s[now].son[mp[x[i]]] == 0)
return 0;
else now = s[now].son[mp[x[i]]];
}
return s[now].ans;
}
}Tree;
int T, n, q;
string s;
int id;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> T;
for1(i,'A','Z')
mp[i] = ++ id;
for1(i,'a','z')
mp[i] = ++ id;
for1(i,'0','9')
mp[i] = ++ id;
while(T--)
{
cin >> n >> q;
for1(i,0,Tree.cnt)
Tree.Clear(i);
Tree.cnt = 0;
for1(i,1,n)
{
cin >> s;
s = " " + s;
Tree.Insert(s);
}
for1(i,1,q)
{
cin >> s;
s = " " + s;
cout <<Tree.Query(s) <<'\n';
}
}
return 0;
}
manacher P3805 【模板】manacher 算法
#include<bits/stdc++.h>
#define ll long long
#define bug(x,y) cout << x << ' ' << y << endl;
#define for1(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
const ll maxn = 3e7 + 5;
int n,len[maxn],ans;
string a,s;
void manacher()
{
int mxr = 0;
int mid ;
for1(i,1,s.size() - 1)
{
if(i < mxr)
len[i] = min(len[(mid << 1) - i], len[mid]+mid - i);
else
len[i] = 1;
while(s[i+len[i]] == s[i - len[i]]) len[i] ++;
if(len[i] + i > mxr)
{
mxr = len[i] + i;
mid = i;
}
}
}
void Change()
{
s = "##";
for1(i,0,a.size() - 1)
{
s += a[i];
s += '#';
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> a;
Change();
manacher();
for1(i,1,s.size() - 1)
ans = max(ans,len[i]);
cout <<ans - 1;
return 0;
}
P1368 【模板】最小表示法
#include<bits/stdc++.h>
#define ll long long
#define for1(i,a,b) for(register ll i = a;i <= b;i ++)
using namespace std;
const int maxn = 2e6 + 5;
int n,a[maxn];
int MinShow()
{
int i = 0,j = 1,k = 0;
while(i < n && j < n && k < n)
{
if(a[(i + k)%n] == a[(j + k)%n])
k ++;
else{
if(a[(i + k)%n] > a[(j + k)%n])
i += k + 1;
else j += k + 1;
if(i == j) i ++;
k = 0;
}
}
return min(i,j);
}
//因为这玩意本来是用来匹配字符串
//,加上还有取模,所以从0开始比较方便
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n ;
for1(i,0,n - 1)
cin >> a[i];
int ans = MinShow();
for1(i,0,n - 1)
cout << a[(i + ans) % n] << ' ';
return 0;
}
最大表示法
(和最小表示法相比只变了一个大于小于号)
#include<bits/stdc++.h>
#define ll long long
#define for1(i,a,b) for(register ll i = a;i <= b;i ++)
using namespace std;
const int maxn = 2e6 + 5;
int n,a[maxn];
int MinShow()
{
int i = 0,j = 1,k = 0;
while(i < n && j < n && k < n)
{
if(a[(i + k)%n] == a[(j + k)%n])
k ++;
else{
if(a[(i + k)%n] < a[(j + k)%n])
i += k + 1;
else j += k + 1;
if(i == j) i ++;
k = 0;
}
}
return min(i,j);
}
//因为这玩意本来是用来匹配字符串
//,加上还有取模,所以从0开始比较方便
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n ;
for1(i,0,n - 1)
cin >> a[i];
int ans = MinShow();
for1(i,0,n - 1)
cout << a[(i + ans) % n] << ' ';
return 0;
}
AC 自动机1 P3808 【模板】AC 自动机(简单版)
#include<bits/stdc++.h>
#define ll long long
#define for1(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
const int maxn = 1e6 + 5;
struct Point{
int son[30];
int fail;
int tag;
// Point()
// {for1(i,1,27) son[i] = 0;tag = 0;}
};
struct ac{
Point s[maxn << 2];
int cnt;
ac(){cnt = 0;}
void Build(string x)
{
int now = 0;
for1(i,1,x.size() - 1)
{
if(s[now].son[x[i] - 'a' + 1] == 0)
s[now].son[x[i] - 'a' + 1] = ++cnt;
now = s[now].son[x[i] - 'a' + 1];
}
s[now].tag ++ ;
}
void GetFail()
{
queue<int>dl;
for1(i,1,26)
if(s[0].son[i] != 0)
s[s[0].son[i]].fail = 0,dl.push(s[0].son[i]);
while(!dl.empty())
{
int x = dl.front();
dl.pop();
for1(i,1,26)
{
if(s[x].son[i] != 0)
{
s[s[x].son[i]].fail = s[s[x].fail].son[i];
dl.push(s[x].son[i]);
}
else s[x].son[i] = s[s[x].fail].son[i];
}
}
}
int Query(string x)
{
int now = 0;
int ans = 0;
for1(i,1,x.size() - 1)
{
now = s[now].son[x[i]-'a' + 1];
for(int j = now;j && s[j].tag != -1;j = s[j].fail)
{
ans += s[j].tag;
s[j].tag = -1;
}
}
return ans;
}
}Tree;
int ans;
string s;
int n, q;
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(nullptr);
cin >> n;
for1(i,1,n)
{
cin >> s;
s = " " + s;
Tree.Build(s);
}
Tree.GetFail();
cin >> s;
s = " " + s;
cout << Tree.Query(s) << '\n';
return 0;
}
AC 自动机2 P3796 【模板】AC 自动机(加强版)
#include<bits/stdc++.h>
#define ll long long
#define for1(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
const int maxn = 1e6 + 5;
struct Point{
int son[30];
int fail;
int tag;
// Point()
// {for1(i,1,27) son[i] = 0;tag = 0;}
};
struct node{
int val;
int pos;
}ans[maxn];
bool operator <(const node &x,const node &y)
{
if(x.val != y.val)
return x.val > y.val;
else
return x.pos < y.pos;
}
struct ac{
Point s[maxn << 2];
int cnt;
ac(){cnt = 0;}
void Clear(int x)
{
memset(s[x].son,0,sizeof(s[x].son));
s[x].fail=0;
s[x].tag=0;
}
void Build(string x,int num)
{
int now = 0;
for1(i,1,x.size() - 1)
{
if(s[now].son[x[i] - 'a' + 1] == 0)
s[now].son[x[i] - 'a' + 1] = ++cnt;
now = s[now].son[x[i] - 'a' + 1];
}
s[now].tag = num ;
}
void GetFail()
{
queue<int>dl;
for1(i,1,26)
if(s[0].son[i] != 0)
s[s[0].son[i]].fail = 0,dl.push(s[0].son[i]);
while(!dl.empty())
{
int x = dl.front();
dl.pop();
for1(i,1,26)
{
if(s[x].son[i] != 0)
{
s[s[x].son[i]].fail = s[s[x].fail].son[i];
dl.push(s[x].son[i]);
}
else s[x].son[i] = s[s[x].fail].son[i];
}
}
}
void Query(string x)
{
int now = 0;
for1(i,1,x.size() - 1)
{
now = s[now].son[x[i]-'a' + 1];
for(int j = now;j;j = s[j].fail)
ans[s[j].tag].val ++;
}
return ;
}
}Tree;
string s[100000];
int n, q;
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(nullptr);
while(1)
{
cin >> n;
if(n == 0) break;
for1(i,0,Tree.cnt)
Tree.Clear(i);
Tree.cnt = 0;
for1(i,1,n) ans[i] = (node){0,0};
for1(i,1,n)
{
cin >> s[i];
ans[i].pos = i;
string res = " " + s[i];
Tree.Build(res,i);
}
Tree.GetFail();
cin >> s[0];
string res = " " + s[0];
Tree.Query(res);
sort(ans + 1, ans + n + 1);
cout << ans[1].val <<'\n';
cout <<s[ans[1].pos] << '\n';
for1(i,2,n)
{
if(ans[i].val == ans[i - 1].val)
cout <<s[ans[i].pos] << '\n';
else break;
}
}
return 0;
}
AC自动机3 P5357 【模板】AC 自动机(二次加强版)
#include<bits/stdc++.h>
#define ll long long
#define for1(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
const int maxn = 2e6 + 5;
struct Point{
int son[30];
int fail;
int tag;
int ans;
// Point()
// {for1(i,1,27) son[i] = 0;tag = 0;}
};
struct tu{
int nex;
int to;
}tu[maxn];
int hd[maxn],jitu;
void ru(int x, int y)
{
tu[++jitu].nex = hd[x];
tu[jitu].to = y;
hd[x] = jitu;
}
struct node{
int val;
int pos;
}ans[maxn];
map<int,int> mp;
int in[maxn];
struct ac{
Point s[maxn << 2];
int cnt;
ac(){cnt = 0;}
void Clear(int x)
{
memset(s[x].son,0,sizeof(s[x].son));
s[x].fail=0;
s[x].tag=0;
}
void Build(string x,int num)
{
int now = 0;
for1(i,1,x.size() - 1)
{
if(s[now].son[x[i] - 'a' + 1] == 0)
s[now].son[x[i] - 'a' + 1] = ++cnt;
now = s[now].son[x[i] - 'a' + 1];
}
if(s[now].tag == 0) s[now].tag = num;
mp[num] = s[now].tag;
}
void GetFail()
{
queue<int>dl;
for1(i,1,26)
if(s[0].son[i] != 0)
s[s[0].son[i]].fail = 0,dl.push(s[0].son[i]);
while(!dl.empty())
{
int x = dl.front();
dl.pop();
for1(i,1,26)
{
if(s[x].son[i] != 0)
{
s[s[x].son[i]].fail = s[s[x].fail].son[i];
in[s[s[x].son[i]].fail] ++;
dl.push(s[x].son[i]);
}
else s[x].son[i] = s[s[x].fail].son[i];
}
}
}
void Query(string x)
{
int now = 0;
for1(i,1,x.size() - 1)
{
now = s[now].son[x[i]-'a' + 1];
// for(int j = now;j;j = s[j].fail)
s[now].ans++;
}
return ;
}
void tuopu()
{
queue<int > dl;
for1(i,1,cnt)
if(in[i] == 0)
dl.push(i);
while(!dl.empty())
{
int x = dl.front();
dl.pop();
ans[s[x].tag].val = s[x].ans;
int v = s[x].fail;
in[v]--;
s[v].ans += s[x].ans;
if(in[v] == 0)
dl.push(v);
}
}
}Tree;
string s[200005];
int n, q;
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(nullptr);
cin >> n;
for1(i,1,n)
{
cin >> s[i];
ans[i].pos = i;
s[i] = " " + s[i];
Tree.Build(s[i],i);
}
Tree.GetFail();
cin >> s[0];
s[0] = " " + s[0];
Tree.Query(s[0]);
Tree.tuopu();
for1(i,1,n)
cout << ans[mp[i]].val << '\n';
return 0;
}
哈夫曼树
#include<iostream>
#include<queue>
#define maxn 1e9+7
#define mp(a,b) make_pair(a,b)
#define for1(i,a,b) for(int i = a;i <= b;i++)
using namespace std;
priority_queue<pair<int,int>> q;
struct node{
int parent;
int ls;
int rs;
int data;
int yezi;
}a[2000005];
int d[100005],cnt=0,root,n;
int top = 1,zhan[100005];
void ru(int x)
{
a[++cnt].data = x;
a[cnt].yezi = 1;
}
void cl(int x, int y)
{
a[++cnt].data = a[x].data+a[y].data;
a[cnt].ls = x;
a[cnt].rs = y;
a[x].parent = cnt;
a[y].parent = cnt;
a[cnt].yezi = 0;
}
void dfs(int now)
{
if(a[now].yezi == 1)
{
cout << a[now].data <<" :";
for1(i,1,top-1)
cout << zhan[i];
cout << endl;
return ;
}
zhan[top++] = 0;
dfs(a[now].ls);
top--;
zhan[top++] = 1;
dfs(a[now].rs);
top--;
return ;
}
int main()
{
int x,y;
cin >> n;
for1(i,1,n)
{
cin >> d[i];
q.push(mp(-d[i],i));
ru(d[i]);
}
while(!q.empty())
{
x = q.top().second;
q.pop();
if(q.empty()) break;
y = q.top().second;
q.pop();
cl(x,y);
q.push(mp(-(a[x].data+a[y].data),cnt));
}
root = x;
dfs(root);
return 0;
}
// 5
// 1 2 3 4 5

浙公网安备 33010602011771号