zoukankan      html  css  js  c++  java
  • 括号序列

    括号序列

    题目描述

     

    可怜不喜欢括号序列,但是她发现总是有人喜欢出括号序列的题。

    为了让全世界都能感受到她的痛苦,她想要写一个转换器:它能把普通的小写字符串转换成长度相同的合法的括号序列。

    在可怜的构思中,这样的转换器需要满足如下两个条件:

      1.结果的括号序列必须要是合法的,即左右括号必须要是相匹配的。

      2.对于一堆相匹配的左右括号,他们所在的位置原来的小写字母必须相同。

    举例来说,对于字符串aabaab,()(())就是一个合法的答案,而()()()不满足第二个条件,  (((())不满足第一个条件。

    可怜发现对于一个小写字符串,有时候有很多满足条件的括号序列,有些时候一个都没有。

    于是可怜给出了一个小写字符串,她想让你帮她算一下,有多少个不同的子串满足能转换成合法的括号序列。

     

    输入

     

    输入一行一个小写字符串s。

     

    输出

     

    输出一行一个整数,表示答案。


    solution

    首先我们考虑暴力每一个起点,用栈维护。当栈为空时,满足j~i为合法的位置。

    效率O(n^2)

    那么显然是T了,我们考虑从头开始只维护一个栈,记录下每一个位置的栈的状态。

    状态用hash值表示

    显然相同状态的栈可以互相贡献,那我们排序一下,统计就行。

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ll unsigned long long
    #define p 998244353
    #define maxn 1000006
    using namespace std;
    int n,id[maxn],top;
    char ch[maxn],zh[maxn];
    ll s[maxn];
    int main()
    {
        scanf("%s",ch+1);
        s[0]=0;n=strlen(ch+1);
        for(int i=1;i<=n;i++){
            if(top>0&&ch[i]==zh[top]){
                s[i]=s[id[top]];top--;
            }
            else {
                zh[++top]=ch[i];id[top]=i-1;
                s[i]=s[i-1]*p+ch[i];
            }
        }
        //for(int i=0;i<=n;i++)cout<<s[i]<<endl;
        sort(s,s+n+1);
        int i=0;
        long long ans=0;
        while(i<=n){
            int j=i;while(s[j]==s[i]&&j<=n)j++;
            int l=j-i;
            ans=ans+(1LL)*l*(l-1)/2;
            i=j;
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    Python内置函数(22)——list
    Git在不同环境换行符设置
    Spring之AOP
    Spring之IOC
    Spring--框架简介
    git-远程协作
    git-SSH连接配置
    git-本地操作
    git简介
    浅谈Sql各种join的用法
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358767.html
Copyright © 2011-2022 走看看