zoukankan      html  css  js  c++  java
  • luogu 字符串口胡合集

    P3065 [USACO12DEC]第一!First!

    建立trie树,对于每个字符串的每个字符,容易想到必定小于他的兄弟字符,用拓扑排序判断是否有冲突即可

    P4070 [SDOI2016]生成魔咒

    求S每个前缀有多少本质不同的子串 

    可知SAM每次加入一个字符后增加的本质不同的字符串是新增的结点maxlen[np] - minlen[np] + 1 = len[np] - len[fa[np]]

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int maxn = 1e5 + 10;
    int len[maxn << 1],fa[maxn << 1];
    unordered_map<int,int> son[maxn << 1];
    int size,last;
    void Init(){
        size = last = 1;
    }
    int insert(int s){
        int p = last,np= ++size; last = np;
        len[np] = len[p] + 1;
        for(;p && !son[p].count(s);p = fa[p]) son[p][s] = np;
        if(!p) fa[np] = 1;
        else{
            int q = son[p][s];
            if(len[p] + 1 == len[q]) fa[np] = q;
            else{
                int nq = ++size; len[nq] = len[p] + 1;
                son[nq] = son[q];
                fa[nq] = fa[q]; fa[q] = fa[np] = nq;
                for(;son[p].count(s) && son[p][s] == q && p;p = fa[p]) son[p][s] = nq;
            }
        }
      //  cout << len[last] << " " << len[fa[last]] << endl;
        return len[last] - len[fa[last]];
    }
    int N;
    int main(){
        scanf("%d",&N);
        LL sum = 0; Init();
        for(int i = 1; i <= N ; i ++){
            int x; scanf("%d",&x);
             sum += insert(x);
             printf("%lld
    ",sum);
        }
        return 0;
    }
    View Code

    P3346 [ZJOI2015]诸神眷顾的幻想乡

    学了一下广义后缀自动机(似乎就是把所有字符串建在同一个SAM上),然后她就是模板题了

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int maxn = 1e6 + 10;
    int len[maxn << 1],fa[maxn << 1];
    int son[maxn << 1][10];
    int size;
    void Init(){
        size = 1;
    }
    int insert(int s,int last){
        int p = last,np= ++size;
        len[np] = len[p] + 1;
        for(;p && !son[p][s];p = fa[p]) son[p][s] = np;
        if(!p) fa[np] = 1;
        else{
            int q = son[p][s];
            if(len[p] + 1 == len[q]) fa[np] = q;
            else{
                int nq = ++size; len[nq] = len[p] + 1;
                memcpy(son[nq],son[q],sizeof(son[q]));
                fa[nq] = fa[q]; fa[q] = fa[np] = nq;
                for(;son[p][s] && son[p][s] == q && p;p = fa[p]) son[p][s] = nq;
            }
        }
        return np;
    }
    int N,c;
    struct Edge{
        int to,next;
    }edge[maxn * 2];
    int head[maxn],tot;
    void init(){
        for(int i = 0 ; i <= N ; i ++) head[i] = -1;
        tot = 0;
    }
    void add(int u,int v){
        edge[tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    int a[maxn];
    int ind[maxn];
    void dfs(int u,int la,int last){
        last = insert(a[u],last);
        for(int i = head[u]; ~i ; i = edge[i].next){
            int v = edge[i].to;
            if(v == la) continue;
            dfs(v,u,last);
        }
    }
    int main(){
        scanf("%d%d",&N,&c);
        Init(); init();
        for(int i = 1; i <= N ; i ++) scanf("%d",&a[i]);
        for(int i = 1; i <= N - 1; i ++){
            int u,v; scanf("%d%d",&u,&v);
            add(u,v); add(v,u); ind[u]++; ind[v]++;
          //  cout << u << " " << v << endl;
        }
        for(int i = 1; i <= N ; i ++){
            if(ind[i] == 1){
                 dfs(i,-1,1);
            }
           // cout << i << " " << ind[i] << endl;
        }
        LL ans = 0;
        for(int i = 1; i <= size; i ++) ans += len[i] - len[fa[i]];
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    C#-----类DateTime的常用方法
    C#-----字节数组(byte[])和字符串相互转换
    maven执行update命令时报org/apache/maven/shared/filtering/MavenFilteringException错误
    关于dubbo服务的xml配置文件报错的问题
    The method getTextContent() is undefined for the type Node
    jetty各个版本对应的jdk版本
    dubbo启动报java.lang.ClassNotFoundException: javassist.ClassPath
    MAC下安装多版本JDK和切换几种方式
    安装第三方jar包的两种方式
    使用 Nexus 搭建私服仓库时我犯的一个小错误
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/11761394.html
Copyright © 2011-2022 走看看