zoukankan      html  css  js  c++  java
  • 「考试总结」2021-01-25 口胡

    T1

    首先有"本质不同的回文串的数量级是 (O(n)) 的"

    证明很简单,考虑sam上最多有 (2n-1) 个节点,同时这些节点中每个最多有一个回文串

    (如果有多个的话,那么短串的 (endpos) 比长串要多)

    其实在这个题目里面关注的是 (midpos),那么给所有的回文串标号

    (manacher) 处理所有的回文中心,把短串向长串连边得到一个树

    对于每次处理的 (id[i-r[i]+1,i+r[i]-1]) 异或上 (i) 最后按照 (SAM) 维护 (endpos) 个数那样维护 (midpos) 的异或和即可

    一开始想的是倍增后缀树的做法,其实和正解是一致的,考完了之后优化了一下思路写了出来

    所以以后要注意的是难题口胡完了要写

    复杂度 (Theta(n))

    注意的几个点:

    (1.) 手写 (hash)

    (2.) 字符串清空一定要手动清全,因为 (t[i]) 后面的遗留可能对计算造成影响

    (3.) 森林的根节点的 (res[x]) 不能取最大值

    T2

    子串排名递减,总和增加,所以两者交点最多有一个,二分统计即可

    但是考试的时候不会如何求排名,所以 (SAM) 维护子串排名方式如下:

    每个后缀树上的点维护的是一个后缀,那么我们翻转之后就能得到前缀

    先算 (endpos) 大小表示这个点一共多少个串

    然后把所有的出边都标号,标号就是 (s[pos[x]+len[fa[x]]])

    这样每个点在后缀树上排序之后再 (dfs) 得到每个点的 (rk)

    对于每个 ([l,r]) 倍增出来对应的点之后直接 (rk[now]+len[now]-(r-l+1)+1) 即可

    T3

    后缀自动机板子题,不过考试的过程中发现 (dfs) 会本地爆栈,浪费了很多时间回忆如何写基数排序,如下:

    for(reg int i=1;i<=tot;++i) ton[len[i]]++; 
            for(reg int i=1;i<=slen;++i) ton[i]+=ton[i-1]; 
            for(reg int i=tot;i>=1;--i) id[ton[len[i]]--]=i;
            for(reg int i=tot;i>=1;--i){
                if(sz[id[i]]>1) ans=max(ans,1ll*sz[id[i]]*len[id[i]]); 
                sz[fa[id[i]]]+=sz[id[i]];
            } printf("%lld
    ",ans);
    

    端正态度,加速思考

  • 相关阅读:
    SoapUI开源版简单定制报告1
    python json模块 字典 输出中文
    Django文件上传机制用法详解(转)
    选择排序
    插入排序
    Python单元测试框架 unittest
    Design Pattern —— Prototype /Template Method/Iterator/Composite/Bridge
    Design Pattern ——Factory Method&Abstract Factory
    Design Pattern ——Builder
    JAVA泛型那些事儿
  • 原文地址:https://www.cnblogs.com/yspm/p/14324423.html
Copyright © 2011-2022 走看看