zoukankan      html  css  js  c++  java
  • 串串乱记(长期

    这里贴板子, 近一周每天都要打截止那天早上已经会的。

    知识笔记贴在:

    note 1

    理解后缀排序

    LCP部分性质/证明 与后缀数组的 rk 数组与 height 数组


    KMP模板

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e6 + 233;
    
    char s1[N], s2[N];
    int l_1, l_2;
    int fil[N];
    
    int main()
    {
    	scanf("%s%s",s1+1,s2+1);
    	l_1 = strlen(s1+1), l_2 = strlen(s2+1);
    	fil[1]=0;
    	for(int i=2,j=0; i<=l_2; ++i) {
    		while(j && s2[j+1]!=s2[i]) j=fil[j];
    		if(s2[j+1] == s2[i]) ++j;
    		fil[i] = j;
    	}
    	for(int i=1,j=0; i<=l_1; ++i) {
    		while(j && (j==l_2 || s2[j+1]!=s1[i])) j=fil[j];
    		if(s2[j+1] == s1[i]) ++j;
    		if(j==l_2) cout << (i-l_2+1) << '
    ';
    	}
    	for(int i=1; i<=l_2; ++i) cout << fil[i] << ' ';
    	return 0;
    }
    

    AC 自动机板子

    struct acam{
    	int tr[N][26], fil[N], fa[N], tot;
    	void ins(char *s, int n)
    	{
    		int x=0;
    		for(int i=0 i<n; ++i) {
    			char  ch = s[i] - 'a';
    			if(!tr[x][ch]) {
    				int y = ++tot;
    				tr[x][ch] = y;
    				fa[y] = x;
    			}
    			x = tr[x][ch];
    		}
    	}
    	void get_fail()
    	{
    		queue<int>q;
    		for(int i=0; i<26; ++i)
    			if(tr[0][i]) q.push(tr[0][i]), fil[tr[0][i]] = 0;
    		while(!q.empty())
    		{
    			int x = q.front(); q.pop();
    			for(int i=0; i<26; ++i)
    				if(tr[x][i]) fil[tr[x][i]] = tr[fil[x]][i], q.push(tr[x][i]);
    				else tr[x][i] = tr[fil[x]][i];
    		}
    	}
    } A;
    

    倍增后缀排序

    //nlogn倍增后缀排序
    char s[MAXN];
    
    int c[MAXN];
    int x[MAXN];
    int y[MAXN];
    int sa[MAXN];
    
    inline void get_sa(int n, int m) {
    	for(int i = 1; i <= n; ++i) ++c[x[i] = s[i]];
    	for(int i = 1; i <= m; ++i) c[i] += c[i-1];
    	for(int i = n; i >= 1; --i) sa[c[x[i]]--] = i;
    	for(int w = 1, q = 0; w < n; w <<= 1, q = 0) {
    		for(int i = n-k+1; i <= n; ++i) y[++q] = i;
    		for(int i = 1; i <= n; ++i) if(sa[i] > k) y[++q] = sa[i] - k;
    		for(int i = 1; i <= m; ++i) c[i] = 0;
    		for(int i = 1; i <= n; ++i) c[x[i]]++;
    		for(int i = 1; i <= m; ++i) c[i] += c[i-1];
    		for(int i = n; i >= 1; --i) sa[c[x[y[i]]]--] = y[i];
    		swap(x, y); x[sa[1]] = q = 1;
    		for(int i=2; i<=n; ++i)
    			x[sa[i]] = y[sa[i]] == y[sa[i-1]] && y[sa[i] + w] == y[sa[i-1] + w] ? q : ++q;
    		if(q == n) break;
    		m = q;
    	}
    }
    

    rk + height 数组

    int rk[N], height[N];
    inline void get_height() {
    	for(int i=1; i<=n; ++i) rk[sa[i]] = i;
    	for(int i=1, j, k=0; i<=n; ++i) {
    		if(rk[i]==1) continue;
    		j = sa[rk[i] - 1]; k -= k>0;
    		while(i+k<=n && j+k<=n && s[i+k]==s[j+k]) ++k;
    		height[rk[i]] = k;
    	}
    }
    
  • 相关阅读:
    删除字符串组中相同元素,并删除值为空的元素 (转载,笔记)
    获取操作系统语言
    .net 传递中文参数解决办法
    古怪问题:vs2003程序 在繁体平台下控件位置发生变化
    Godaddy邮箱C#发送邮件设置
    无法显示隐藏文件的解决方法
    虚拟机文件
    sql 2000 修复问题
    看QQ是否在线
    sql 知识摘录
  • 原文地址:https://www.cnblogs.com/tztqwq/p/14198850.html
Copyright © 2011-2022 走看看