CSP-S brush training record title

$ CSP.S $ brushes training title record:

$ By~wcwcwch $





A string topics:



1. [template] $ manacher $ algorithm

Model: Determine all the palindromic sequence position and length of the string $ $ S.

Personal understanding: to solve such problems, the palindromic symmetry properties of the most important string.

On the complexity of the key word: $ f [i] = min ~ (~ ri ~, ~ f [~ mid \ times2-i ~] ~) ~ $ (to achieve different, the boundary may be different)

The min $ $ $ RI $ function is left to the current position from the palindromic sequence it belongs to the boundary, the right $ mid \ times 2 -1 $ is the corresponding position on the other side it belongs to a palindromic sequence. If you take the left, then I use the current location extensions (palindrome string would exceed the current boundary) so must be able to make $ r $ extension to the right; if we can obtain the right, we find that due to the palindrome string of symmetry, this position can not continue to be inevitable external expansion, because he most begin to spread the inevitable or a palindromic sequence within the boundaries (or left $ min $ function certainly taken) in the present, and if it palindromic sequence within the current expansion, its symmetrical position $ mid \ also times 2 -1 $, and $ f [~ mid \ times2-i ~] $ it is the maximum extension, contradictory.

To summarize, if $ $ min function takes the left, then the $ $ necessarily extend right R & lt; If we take the right, then the complexity of $ 1 $ (constant). Then R & lt complexity $ $ $ times and the range of $ 1, $ n-neither exceeding $, so complexity is $ O (2 \ times n) $, even when applied together with the process "# "No, nothing is constant.



2. [template] Extended $ KMP $

Model: there is a string of $ a $, $ A $ required output [se] and [$ A $] each suffix longest common prefix.

Combined product $ KMP $ and $ Manacher $ Thought. But personally more inclined $ Manacher $. Calculation and because of his $ Manacher $ quite similar, are first obtained according to a certain position before a result of the initial length of the common prefix is ​​"palindromic sequence" becomes the longest common prefix string center $ palindromic MID $ becomes longest common prefix left point $ l $, $ last long min $ function is not the same.

Our $ $ a deal for it [the beginning of each suffix] and [itself] $ a $ longest common prefix of $ f [i] $. Note that we start from second place, because $ f [1] = | a | $ very special. We L $ $ $ record has traversed the I $ $ i + f [i] $ maximum $ i $, $ R & lt simultaneously with the recording $ $ i + f [i] $, $ are both initial 0 $. Then: $ f [i] = min (~ ri ~, ~ f [i-l + 1] ~) $, and the calculation equation like $ Manacher $, $ I $ is the initial value in a common prefix, $ I $ then following the letter and some $ f [i-l + 1] $ following the letter in the consistency range of $ $ RI, then it can be directly used as an initial value. Complexity and above $ Manacher $ prove the same!

$ code $ :

int n,m;
int f[2000005];
string s,a;

int main(){
    cin>>a; n=a.size();
    cin>>s; m=s.size();
    s=' '+s+'#'+a; n+=m+2; //加到一起
    rg l=0,r=0; f[1]=m; //第一个不管
    for(rg i=2;i<=n;++i){
        if(i<=r) f[i]=min(r-i,f[i-l+1]); //确定初始值
        while(s[f[i]+1]==s[i+f[i]]) ++f[i]; //向后扩展
        if(i+f[i]-1>r) l=i,r=i+f[i]-1; //更新l和r的值
    }
    for(rg i=1;i<=m;++i) printf("%d%c",f[i],i==m?'\n':' ');
    for(rg i=m+2;i<n;++i) printf("%d%c",f[i],i==n-1?'\n':' ');
    return 0;
}


LOJ ~ $ 3095 $ 3.: $ 2019 $ ~ string Snoi

Title summarized: to a length of string $ $ $ n-S $, denoted S $ S'_i $ $ $ represents $ I $ omitted after a string of characters obtained, output: \ ((S'_1, 1) ... (S'_n, n) \) of lexicographical sort the results. $ N \ leq 10 ^ 6 $

We carefully observe the problem, analyze the sample hand count, you can find a property:

  1. $ I $ disposed starting from the position number, and a next first position different number $ I $ $ J $ location, the $ [i, j-1] $ equal to the string.
  2. If $ a [i] <a [j] $, then the string can be found back as comprising a plurality $ a [i] $ and less than $ [i, j-1] $.
  3. If $ a [i]> a [j] $, then the string can be found back as comprising a plurality $ a [i] $ greater than the $ [i, j-1] $.

So we open to join an array of double-ended, recording the final answer. Complexity is desirable: $ O (n) $

$ code $ :

    n=qr(); cin>>a; a=' '+a; a[n+1]=')'; //防出界
    rg l=0,r=n+1; //记录双端指针
    for(rg i=1;i<=n;++i){ rg j=i;
        while(a[i]==a[i+1])++i; //找到连续相同串的右端点
        if(a[i+1]<a[i]) for(rg k=j;k<=i;++k) s[++l]=k; //这一段都必然比后面的串小
        else for(rg k=i;k>=j;--k) s[--r]=k; //这一段都必然比后面的串大
    }
    for(rg i=1;i<=n;++i) printf("%d ",s[i]);


4. Luo Gu P5446 $ $: $ 2018 ~ $ THUPC and green and strings

Summarizes the meaning of problems: For string $ S $, defined operators $ f (S) $ $ S to the front $ $ | S | -1 $ formed long character reverse connected back to $ S $ $ 2 | S | new string of -1 $. We are now given string $ T $, query string length which does not exceed $ | T | S $ $ $ string through the string operation a number of times obtained $ f $ $ T $ comprising the prefix. $ 1 \ le | T | \ le 5 \ times 10 ^ 6 $.

Very tangled a question, adjusting for a while only to find that thinking is not precise enough to determine wrong.

First, we find that this is a palindrome string of related topics, we can see if there is a position $ i $ S $ string $ string so that it can reach the end of the longest palindrome $ S $ string, then the operation $ [1, i] $ this paragraph characters $ f (1, i) $ must be obtained so that a valid new string S $ $ its prefix. Then we can find the position of the palindromic sequence if these marks, if the string $ S $ $ I $ some positions such that from $ I $ palindromic sequence may be extended to reach the first character string and $ S $ this the last character is marked, then this position is legal! As long as multiple $ f $ operation can be.

$ code $ :

    t=qr();
    while(t--){
        cin>>s; n=s.size(); s=' '+s; //读入
        rg mid=0,r=0; s[0]='('; s[n+1]=')'; //设边界
        for(rg i=1;i<=n;++i){ f[i]=0;
            if(i<r) f[i]=min(r-i,f[(mid<<1)-i]); //manacher寻找初值
            while(s[i-f[i]-1]==s[i+f[i]+1]) ++f[i]; //扩展
            if(i+f[i]>r) mid=i,r=i+f[i]; //更新
        } k[n]=1;
        for(rg i=n;i>=1;--i) //如果转一次就合法,或者能够连转多次
            if(i+f[i]==n||(i-f[i]==1&&k[i+f[i]])) k[i]=1;
        for(rg i=1;i<=n;++i)
            if(k[i])printf("%d ",i),k[i]=0; //输出+清零
        puts("");
    }


5. Luo Gu P4503 $ $: $ CTSC ~ $ 2014 ~ $ ~ QQ $ penguins

Is intended to summarize the question: given a string with wildcards S $ $, wildcards are two, one exactly matches a character, another match any number (including a $ 0 $) characters. Then give $ $ n-strings $ T_i $, $ query match can T_i $ $ S $. $ 1 le n \ le 100, 1 \ le \ | S |, | T_i | \ 5, 0 le $ number le 10 ^ \ wildcard $ \ le 10. $

Finally engage in a $ Hash $ title, the first line should be considered carefully tune the details of the code. For $ Hash $ We have single hash and Duoha Xi, according to the dimension of the element information of view. But still like a single hash in the $ long ~ long $, and the effect is almost double $ int $ hash. $ Long ~ long $ write good, run fast, but the modulus is too easy to overflow; double $ int $ hash (usually with $ STL: pair $), run fast, but correctness is much higher.

This question we can take violent measures, because only one can be different, so we simply enumerate which one is which one, then each string compared with each other except that a prefix and suffix, if it is the same legitimate couple. Comparing prefixes and suffixes may be pretreated $ $ get the Hash.

Complexity is desirable: $ O (m \ times n \ times logn) $

$ code $ :

const ll mod=20190816170251; //纪念CCF关门的日子是个质数
//小常识:1e18+3和1e18+9都是质数很好记,998244353和998244853和993244853也是。

ll ans;
int n,m,k;
ll q[30005];
ll f[30003][202]; //前缀hash
ll s[30003][202]; //后缀hash
char a[30005];

int main(){
    n=qr(); m=qr(); k=qr();
    for(rg i=1;i<=n;++i){
        scanf("%s",a+1); //scanf读入快一点     //107这个数不要太大,防溢出
        for(rg j=1;j<=m;++j) f[i][j]=(f[i][j-1]*107+a[j])%mod; //前缀hash
        for(rg j=m;j>=1;--j) s[i][j]=(s[i][j+1]*107+a[j])%mod; //后缀hash
    } ll x=1;                //模数不能太大,否则这里会炸掉
    for(rg i=1;i<=m;++i){ //每个位置分开做会快些,正确性也高一些
        for(rg j=1;j<=n;++j)
            q[j]=f[j][i-1]*x+s[j][i+1]; //前后合并
        sort(q+1,q+n+1);
        for(rg j=1,o=1;j<=n;j=++o){
            while(q[j]==q[o+1]) ++o; //找到连续一段相同的
            ans+=((ll)(o-j+1)*(o-j))>>1; //注意答案贡献为C[x][2],从一段中取一对
        } x=x*107%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/812-xiao-wen/p/11600101.html