ZJUT2022寒假集训3 字符串1 程序简注

完全的未知领域,只能摸着前辈过河,于是一般时间都花在研读OI-wiki和打模板上了,模板文收获颇丰(

A – 【模板题】manacher 算法

上来就蓝题模板的含金量(

【主站】《试图整一个自己的模板列表》里的对应模板是一样的,以下为按照原理精注版本,不排除将模板文章里的改成减少码量+简化逻辑版本的可能性。

/******************************\
 * Manacher 算法 O(N)
 * Init: si (char si[])
 * Call: manacher(si)
 * Resu: 返回最大回文串长度
 * Comm: 用于在字符串中快速找出最大回文串
\******************************/
namespace lovelive{
    const int MAXN = 11000005;
    char si[MAXN];
    int manacher(char si[]){
        int d1[MAXN],d2[MAXN];
        int l1,r1,l2,r2,len,j,ans;
        len = strlen(si);
        l1 = 0;r1 = -1;
        l2 = 0;r2 = -1;
        ans = 0;
        for(int i=0;i<len;i++){
            //求奇数长度的回文串的Manacher算法
            //Manacher算法的核心是利用对当前边界最右侧
            //的已知回文串的已知信息进行记忆化
            if(i>r1){                   //当前在回文串外面
                d1[i]=1;                //直接使用朴素算法
                while(i-d1[i]>=0 && i+d1[i]<len && si[i-d1[i]]==si[i+d1[i]]){
                    d1[i]++;
                }
            }else{                      //当前在回文串里面
                j = l1 + r1 - i;        //搜索当前回文串的对称位置
                                        //在当前位置之前的回文串都处理完毕了
                                        //所以现在肯定在回文串的后半段
                if(i+d1[j]-1 >= r1){    //如果对称位置的回文串边界超出了当前回文串的边界
                    d1[i] = r1 - i + 1; //不能轻举妄动,因为回文串外的回文性未知
                    while(i-d1[i]>=0 && i+d1[i]<len && si[i-d1[i]]==si[i+d1[i]]){
                        d1[i]++;
                    }                   //喜闻乐见的朴素算法
                }else{
                    d1[i] = d1[j];      //没问题就直接用,没关系的
                }
            }//接下来就该记录答案了
            //无论如何请不要忘记更新边界值
            if(r1==-1 || r1<i+d1[i]-1) r1 = i+d1[i]-1, l1 = i-d1[i]+1;
            ans = max(ans,2*d1[i]-1);

            //求偶数长度的回文串的Manacher算法
            //与奇数版本基本相同,注意相关计算的更改
            //这里选择在偶数长度回文串的右中心记录值
            if(i>r2){
                d2[i] = 0;              //偶数长度回文可能不存在,初始置0
                while(i-d2[i]-1>=0 && i+d2[i]<len && si[i-d2[i]-1]==si[i+d2[i]]){
                    d2[i]++;
                }
            }else{
                j = l2 + r2 - i + 1;    // * * ! * + + * * ! *
                                        // 0 1 2 3 4 5 6 7 8 9  
                if(i+d2[j]-1 >= r2){
                    d2[i] = r2 - i + 1;
                    while(i-d2[i]-1>=0 && i+d2[i]<len && si[i-d2[i]-1]==si[i+d2[i]]){
                        d2[i]++;
                    }
                }else{
                    d2[i] = d2[j];
                }
            }
            //偶数长度回文串可能不存在
            if(d2[i] && r2<i+d2[i]-1) r2 = i+d2[i]-1, l2 = i-d2[i];
            ans = max(ans,2*d2[i]);
        }
        return ans;
    }
}

B – Palindrome

多组数据版本的A题,就不再重复代码了。

F – 【模板题】扩展 KMP(Z 函数)

为了学这个紫题扩展KMP于是把普通KMP也一道学掉了(模板在上文提到多次的模板文里了),然后发现扩展KMP的思想更像是 manacher 算法。

const int MAXN = 20000005;
char source[MAXN],target[MAXN];
LL res[MAXN*2];
namespace lovelive{
    LL ans1,ans2;
    int szs,szt;
    inline char nico(int i){
        return i<szt?target[i]:(i==szt?'#':source[i-szt-1]);
    }
    void z_func(){
        int len = szs + szt + 1, l=0, r=0;
        for(int i=1;i<len;i++){
            if(i<=r && res[i-l] < r-i+1){
                res[i] = res[i-l];
            }else{
                res[i] = max(0,r - i + 1);
                while(i+res[i]<len && nico(res[i])==nico(i+res[i])){
                    res[i]++;
                }
            }
            if(i+res[i]-1 > r) l = i, r = i+res[i]-1;

            if(i<szt) ans1 ^= (res[i]+1) * (i+1);
            if(i>szt) ans2 ^= (res[i]+1) * (i-szt);
            //cout<<i<<"\t"<<res[i]<<endl;
        }
    }
    void main(){
        scanf("%s",source);
        scanf("%s",target);
        szs = strlen(source);
        szt = strlen(target);
        ans1 = szt + 1;
        ans2 = 0;
        res[0] = 0;
        z_func();
        printf("%lld\n%lld\n",ans1,ans2);
        return;
    }
}

J – 【模板题】字典树

什么?它不是黄题,它是一道压缩蓝紫题,遇自动机就会变大变高(

namespace lovelive{
    const int MAXN = 3000005;
    char s[MAXN];
    int n,m;
    class TRIE{
        private:
            int nxt[MAXN][70],nxtc;
            int cnt[MAXN];
            inline int nico(char c){
                if(c>='0'&&c<='9')      return c-'0';
                else if(c>='a'&&c<='z') return c-'a'+10;
                else if(c>='A'&&c<='Z') return c-'A'+36;
                else                    return 66;
            }
        public:
            TRIE(){
                reset(0);
                nxtc = 0;
            }
            void reset(int pnt=0){
                cnt[pnt] = 0;
                for(int i=0;i<=66;i++){
                    nxt[pnt][i] = 0;
                }
            }
            void insert(char *s){
                int p = 0, len = strlen(s);
                for(int i=0;i<len;i++){
                    cnt[p]++;
                    if(!nxt[p][nico(s[i])]){
                        nxt[p][nico(s[i])] = ++nxtc;
                        reset(nxtc);
                    }
                    p = nxt[p][nico(s[i])];
                }
                cnt[p]++;
            }
            int count(char *s){
                int p = 0, len = strlen(s);
                for(int i=0;i<len;i++){
                    if(!nxt[p][nico(s[i])])
                        return 0;
                    p = nxt[p][nico(s[i])];
                }
                return cnt[p];
            }
    }t;

    void main(){
        scanf("%d%d",&n,&m);
        t.reset();
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            t.insert(s);
        }
        for(int i=1;i<=m;i++){
            scanf("%s",s);
            printf("%d\n",t.count(s));
        }
    }
}
知识共享许可协议
《ZJUT2022寒假集训3 字符串1 程序简注》在文章中没有特殊说明的情况下采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。请在转载时注明作者(从现瑕疵)和来源(https://www.zhtg.net.cn/zjut2022_win03/)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇