首页 > 其他分享 >Codeforces 1536B Prinzessin der Verurteilung 题解 [ 紫 ] [ 后缀自动机 ] [ 动态规划 ] [ 拓扑排序 ]

Codeforces 1536B Prinzessin der Verurteilung 题解 [ 紫 ] [ 后缀自动机 ] [ 动态规划 ] [ 拓扑排序 ]

时间:2025-01-15 22:23:46浏览次数:1  
标签:int 题解 der Codeforces Prinzessin 2005 节点 dp define

Prinzessin der Verurteilung:最短未出现字符串的板子。

思路

考虑在 SAM 上 dp,定义 \(dp_i\) 表示从 \(i\) 节点走到 NULL 节点所花费的最少步数。显然我们建出反图,跑 DAG 上 dp 即可。转移如下:

\[dp_i=1+\min_{j=1}^{|v_i|}dp_{v_{i,j}} \]

输出方案的话记录下每个 dp 值的先驱,最后从 \(1\) 号节点开始遍历一遍即可。

注意,如果某个节点某个字母的转移边不存在的话,也需要建边,可以用一个超级源点 \(0\) 把这些 SAM 上不存在的边记录下来,这样才能算出不在里面出现过的字符串。

时间复杂度 \(O(tn|\sum|)\),应该是最优复杂度了。

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
int n,len[2005],fa[2005],ch[2005][26],tot=1,np=1,rd[2005];
char s[1005];
vector<pi>g[2005];
struct node{
    int v=0x3f3f3f3f,frm=-1,cx=-1;
}dp[2005];
void init()
{
    for(int i=0;i<=tot;i++)
    {
        len[i]=fa[i]=0;
        for(int j=0;j<26;j++)ch[i][j]=0;
        dp[i]={0x3f3f3f3f,-1,-1};
        rd[i]=0;
        g[i].clear();
    }
    tot=np=1;
}
void extend(int c)
{
    int p=np;
    np=++tot;
    len[np]=len[p]+1;
    for(;p&&ch[p][c]==0;p=fa[p])ch[p][c]=np;
    if(p==0)fa[np]=1;
    else
    {
        int q=ch[p][c];
        if(len[q]==len[p]+1)fa[np]=q;
        else
        {
            int nq=++tot;
            len[nq]=len[p]+1;
            fa[nq]=fa[q],fa[q]=nq,fa[np]=nq;
            for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq;
            memcpy(ch[nq],ch[q],sizeof(ch[q]));
        }
    }
}
void outp()
{
    int p=1;
    while(p!=-1)
    {
        int v=dp[p].frm,c=dp[p].cx;
        if(c<0)break;
        cout<<char(c+'a');
        p=v;
    }
    cout<<'\n';
}
void solve()
{
    cin>>n>>s+1;
    init();
    for(int i=1;i<=n;i++)extend(s[i]-'a');
    for(int i=1;i<=tot;i++)
    {
        for(int j=0;j<26;j++)
        {
            int v=ch[i][j];
            g[v].push_back({i,j});
            rd[i]++;
        }
    }
    queue<int>q;
    for(int i=0;i<=tot;i++)
    {
        if(rd[i]==0)
        {
            dp[i]={1,-1,-1};
            q.push(i);
        }
    }
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(auto ed:g[u])
        {
            int v=ed.fi,c=ed.se;
            rd[v]--;
            if(rd[v]==0)q.push(v);
            int dpv=dp[u].v+1;
            if(dpv<dp[v].v)
            {
                dp[v].v=dpv;
                dp[v].frm=u;
                dp[v].cx=c;
            }
            else if(dpv==dp[v].v&&dp[v].cx>c)
            {
                dp[v].frm=u;
                dp[v].cx=c;
            }
        }
    }
    outp();
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)solve();
    return 0;
}

标签:int,题解,der,Codeforces,Prinzessin,2005,节点,dp,define
From: https://www.cnblogs.com/zhr0102/p/18673807

相关文章

  • [CF2057G] Secret Message 题解
    神秘题目。题目的条件十分神奇,\(|A|\le\frac{1}{5}(s+p)\),不知所云。一开始尝试用皮克定理转化,但是failed。阅读理解之后发现有一个(很典)的套路,就是构造出五组方案,使得\(\sum_{cyc}|A|=s+p\),这样就一定有一组方案,面积小于等于$\frac{1}{5}(s+p)$。如何构造?我们发现......
  • VP Daiwa Securities Co. Ltd. Programming Contest 2024(AtCoder Beginner Contest 38
    A-Humidifier1题意:一个漏水的桶,在零时刻有零升水,进行\(n\)次加水,在\(t_i\)时刻加\(v_i\)升水,每一时刻会漏一生水,问第n次加水后有多少升水。直接模拟即可,每次加水先减去漏掉的水,注意至少有0升,然后加上新加的水。点击查看代码voidsolve(){intn;std::cin>>n;......
  • AcWing 274. 移动服务 题解
    Tag:线性dp题面link题目描述一个公司有三个移动服务员,最初分别在位置\(1,2,3\)处。如果某个位置(用一个整数表示)有一个请求,那么公司必须指派某名员工赶到那个地方去。某一时刻只有一个员工能移动,且不允许在同样的位置出现两个员工。从\(p\)到\(q\)移动一个员工,需要花费......
  • 第七届传智杯初赛第二场(abc三组)补题+题解python
    文章目录前言A计算商品打折结算金额(B组、C组)B茶杯和球(A组、C组)C游游的字母串(A组、B组、C组)D电梯(B组、C组)E小欧的排列计算(A组、B组、C组)F游游的字母子串(A组、B组、C组)G跳跳跳(A组、B组)H小红的战争棋盘(A组)前言在CSDN上并未找到第七届传智杯......
  • VP Codeforces Round 978 (Div. 2)
    A.BustoPénjamo题意:有n个家庭,每个家庭有\(a_i\)个人,现在有r排座位,每个座位可以坐两个人。如果一个人自己一个坐一个座位或者和自己家庭的人坐一个座位,他就会开心,问所有人都入座后最多有多少人开心。我们肯定尽量让一个座位坐两个同一家庭的人,这样一个座位可以让两个人开心。......
  • 信号与系统(郑君里)第一章-绪论 1-1 课后习题解答
    题目详情(1-1分别判断题图1-1所示各波形是连续时间信号还是离散时间信号,若是离散时间信号是否为数字信号?)答案解析:(a)连续信号模拟信号(b)连续信号量化信号(c)离散信号数字信号(d)离散信号抽样信号(非数字信号)(e)离散信号数字信号(f)离散信号数字信号tips:本道题目考察了连续/......
  • ABC 243题解
    ABC243A-C太水不写了。D题意:从完全二叉树上点\(X\)开始移动,每次移动至父节点、左子节点或右子节点。询问N次移动后所处节点,保证答案小于\(10^{18}\)。解法:忘了过程有可能超longlong浪费两分钟。总之就是每一个向父节点操作会消掉最近一个未消掉的向儿子移动操作,然后......
  • 【WPF】使用RenderTargetBitmap截图的时候位置出现偏移的一些解决办法
    简介在WPF中,如果你需要把控件的渲染画面保存到图片,那么唯一的选择就是RenderTargetBitmap。不过,RenderTargetBitmap是个比较难伺候的主,有时候你以为能工作,但实际上不能;你以为能够正常截图,但实际上截出来的图片是歪的。所以,我总结一下自己项目中遇到的坑和解决办法吧!保存的图片......
  • {LOJ #6041. 「雅礼集训 2017 Day7」事情的相似度 题解
    \(\text{LOJ\#6041.「雅礼集训2017Day7」事情的相似度题解}\)解法一由parent树的性质得到,前缀\(s_i,s_j\)的最长公共后缀实质上就是\(i,j\)在SAM中的\(\operatorname{LCA}\)在SAM中的\(\operatorname{len}\)。让我们考虑如何处理\((l,r)\)区间内的询问。直......
  • OpenGL中Shader LOD失效
    1)OpenGL中ShaderLOD失效2)DoTween的GC优化3)开发微信小程序游戏有没有类似Debug真机图形的方法4)射线和Mesh三角面碰撞检测的算法这是第418篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌握和学习。UWA社区主页:community......