字符串

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

posted @ 2022-02-17 11:35  yyx525jia  阅读(12)  评论(0)    收藏  举报