zoukankan      html  css  js  c++  java
  • [20200722NOIP提高组模拟T4]词韵

    题目链接:

      P4471 [BJWC2018]词韵

     

    题目大意:

      懒得打了,自己看题吧.

    solution:

      由于本题求的是最长公共后缀,所以我们可以想到从末尾倒序构造trie,然后再来分析此题.可以注意到的是,两个词能够押韵,当且仅当它们的关键点在trie上是父子或兄弟关系.所以我们可以考虑树形DP.由于兄弟节点较难维护,所以我们可以在父节点中更新,所以我们只看其子节点.对于一个点$x$,f[x]维护该点的dp值,g[x]维护该点的子节点的子树中最大的连续关键点链值.单词$x$可以从前插入若干个单词,也可以从后插入若干个单词,构成一个押韵的序列,所以根据贪心策略,我们选择g[x]的最大值_和次大值__(没错,它们都是变量名),然后统计dp答案即可.

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #define R register
    #define next exntttttttttttttttt
    #define debug puts("mlg")
    using namespace std;
    typedef int ll;
    typedef long double ld;
    typedef unsigned long long ull;
    inline ll read();
    inline void write(ll x);
    inline void writesp(ll x);
    inline void writeln(ll x);
    struct node{
        ll son[26],cnt;
    }trie[1000000];
    char wn;
    ll c[1000000],h;
    ll n,tot;
    inline void Insert(){
        ll now=0;
        for(;h;h--){
            now=trie[now].son[c[h]]?trie[now].son[c[h]]:(trie[now].son[c[h]]=++tot);
        }
        ++trie[now].cnt;
    }
    ll ans,f[1000000],g[1000000];
    inline void dfs(ll x){
        ll _=0,__=0;
        for(R ll i=0;i<26;i++){
            if(trie[x].son[i]){
                dfs(trie[x].son[i]);
                if(!trie[trie[x].son[i]].cnt) continue;
                f[x]+=trie[trie[x].son[i]].cnt;
                if(g[trie[x].son[i]]>_){
                    __=_;
                    _=g[trie[x].son[i]];
                }
                else if(g[trie[x].son[i]]>__) __=g[trie[x].son[i]];
            }
        }
        if(trie[x].cnt) g[x]=f[x]+_;
        ans=max(ans,_+__+f[x]+trie[x].cnt);
    }
    int main(){
        n=read();
        for(R ll i=1;i<=n;i++){
            while(wn<'a'||wn>'z') wn=getchar();
            h=0;
            while(wn>='a'&&wn<='z') c[++h]=wn-'a',wn=getchar();
            Insert();
        }
        dfs(0);
        writeln(ans);
    }
    inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
    inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
    inline void writesp(ll x){write(x);putchar(' ');}
    inline void writeln(ll x){write(x);putchar('
    ');}
  • 相关阅读:
    Leetcode NO.110 Balanced Binary Tree 平衡二叉树
    Leetcode NO.226 Invert Binary Tree 翻转二叉树
    Leetcode NO.215 Kth Largest Element In An Array 数组中的第K个最大元素
    根据特征的浏览器判断
    Cygwin在打开在当前目录
    【转帖】科学对待 健康养猫 打造快乐孕妇
    解决chrome浏览器安装扩展、应用程序一直处在“检查中”的问题
    对【SQL SERVER 分布式事务解决方案】的心得补充
    关于“点击这里继续访问您选择的百度XXX”
    VBA一例:如何保持文本框焦点
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13362828.html
Copyright © 2011-2022 走看看