• P3294 [SCOI2016]背单词


    P3294 [SCOI2016]背单词

    Trie+贪心

    倒插进树+取出重建+子树处理+贪心遍历

    倒插进树:把后缀转化为前缀,所以把字符串倒着插进Trie中

    取出重建:重新建立一棵以单词为节点的树,如果存在包含(前缀)关系就连边

    子树处理:处理出每棵树的大小用于贪心

    贪心遍历:遍历整棵新树,累加答案

    关于贪心:每次找到最小的子树统计答案

    end.

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using namespace std;
    struct data{
        int nxt[27],end;
        data(){memset(nxt,0,sizeof(nxt)); end=0;}
    }a[510003];
    vector <int> g[100002]; //存边
    int n,cnt,len,siz[100002];
    long long f[100002];
    char q[510003];
    inline bool cmp(const int &A,const int &B) {return siz[A]<siz[B];}
    inline void read_q(){
        char c=getchar(); len=0;
        while(c<'a'||c>'z') c=getchar();
        while('a'<=c&&c<='z') q[len++]=c,c=getchar();
    }
    inline void insert_(int id){ //建树
        read_q();
        int u=0;
        for(int i=len-1;i>=0;--i){
            int p=q[i]-'a';
            if(!a[u].nxt[p]) a[u].nxt[p]=++cnt;
            u=a[u].nxt[p];
        }a[u].end=id; //编号代替单词
    }
    inline void rebuild(int x,int p){ //重新建树
        if(a[x].end) g[p].push_back(a[x].end); //存在前缀关系连边
        for(int i=0;i<26;++i){
            int to=a[x].nxt[i];
            if(!to) continue;
            rebuild(to,a[x].end ? a[x].end:p);
        }
    }
    inline void dfs1(int x){
        siz[x]=1;
        for(int i=0;i<g[x].size();++i){
            int to=g[x][i];
            dfs1(to);
            siz[x]+=siz[to];
        }
        sort(g[x].begin(),g[x].end(),cmp); //按子树从小到大排序
    }
    inline void dfs2(int x){
        f[x]=x? 1:0;
        long long tmp=0;
        for(int i=0;i<g[x].size();++i){
            int to=g[x][i];
            dfs2(to);
            f[x]+=f[to]+tmp; //贪心累加答案
            tmp+=siz[to];
        }
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;++i) insert_(i);
        rebuild(0,0);
        dfs1(0);
        dfs2(0);
        printf("%lld",f[0]);
        return 0;
    }
  • 相关阅读:
    「 HDU P3336 」 Count the string
    Luogu P4016 「 网络流 24 题 」负载平衡问题
    『 学习笔记 』网络最大流
    Luogu P4014 「 网络流 24 题 」分配问题
    Loj #6000.「 网络流 24 题 」搭配飞行员
    牛客练习赛25 C 再编号
    线段树--从入门到入土
    网络流学习--费用流
    网络流--最大流
    五校联考解题报告
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9614349.html
Copyright © 2020-2023  润新知