• SCOI2013 密码


    题目描述:

    Fish是一条生活在海里的鱼。有一天他很无聊,就到处去寻宝。他找到了位于海底深处的宫殿,但是一扇带有密码锁的大门却阻止了他的前进。

    通过翻阅古籍,Fish 得知了这个密码的相关信息:

    1. 该密码的长度为N。

    2. 密码仅含小写字母。

    3. 以每一个字符为中心的最长回文串长度。

    4. 以每两个相邻字符的间隙为中心的最长回文串长度。

    很快Fish 发现可能有无数种满足条件的密码。经过分析,他觉得这些密码中字典序最小的一个最有可能是答案,你能帮他找到这个密码么?

    注意:对于两个串A和B,如果它们的前i个字符都相同,而A的第i+1个字符比B的第i+1个字符小,那么认为是则称密码A 的字典序小于密码B 的字典序,例如字符串abc 字典序小于字符串acb。如果密码A的字典序比其他所有满足条件的密码的字典序都小,则密码A是这些密码中字典序最小的一个。

     题解:
    manacher反演?

    贪心+并查集,判断这一位上字符的时候只需要与前边的1个点制造联系。

    和manacher好像啊。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 100050
    inline int rd()
    {
        int f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n,p[2*N];
    int hed[2*N],cnt;
    struct EG
    {
        int to,nxt;
    }e[4*N];
    void ae(int f,int t)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    int col[2*N],fa[2*N];
    bool vis[28];
    int findfa(int x)
    {
        if(x==fa[x])return x;
        return fa[x]=findfa(fa[x]);
    }
    int main()
    {
        n=rd();
        for(int i=2;i<=2*n;i+=2)
            p[i]=rd();
        for(int i=3;i<=2*n-1;i+=2)
            p[i]=rd();
        for(int i=2;i<=2*n;i++)
            fa[i]=i;
        int mx = 0;
        for(int i=2;i<=2*n;i++)
        {
            for(int j=max(i&1,mx-i+(i&1));j<=p[i];j+=2)
            {
                int f1 = findfa(i-j),f2 = findfa(i+j);
                if(f1!=f2)fa[f2]=f1;
            }
            mx = max(mx,i+p[i]-(i&1));
        }
        for(int i=2;i<=2*n;i++)
        {
            int f1 = findfa(i-p[i]-1);
            int f2 = findfa(i+p[i]+1);
            ae(f2,f1);ae(f1,f2);
        }
        mx=0;
        for(int i=2;i<=2*n;i+=2)
        {
            int ff = findfa(i);
            if(!col[ff])
            {
                for(int j=1;j<=26;j++)vis[j]=0;
                for(int j=hed[ff];j;j=e[j].nxt)
                    vis[col[e[j].to]]=1;
                for(int j=1;j<=26&&!col[ff];j++)
                    if(!vis[j])col[ff]=j;
            }
            printf("%c",col[ff]+'a'-1);
            if(i+p[i]-1>mx)
            {
                for(int j=mx+2;j<=i+p[i]-1;j+=2)
                    col[j]=col[i*2-j];
                mx=i+p[i]-1;
            }
        }
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    JsBridge踩坑之WebViewJavascriptBridge is undefined,找不到Bridge对象
    Android踩坑之couldn't find "libClingSDK.so"
    GDM, KDM, LightDM, SDDM的区别和安装配置
    安装完ubuntu需要做得事
    apt vs snap
    在shell下执行命令的方法
    Vimmer一套全语言支持的完美Vim配置——附Monaco字体
    Ubuntu gnome安装Monaco字体,FontForge module is probably not installed
    Ubuntu全方位美化,定制教程
    stm32--FatFs调试过程(SPIFlash)
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10046183.html
Copyright © 2020-2023  润新知