zoukankan      html  css  js  c++  java
  • [JZOJ 5893] [NOIP2018模拟10.4] 括号序列 解题报告 (Hash+栈+map)

    题目链接:

    https://jzoj.net/senior/#main/show/5893

    题目:

    题解:

    考虑暴力怎么做,我们枚举左端点,维护一个栈,依次加入元素,与栈顶元素和栈内第二个元素相同时弹出栈顶和第二个元素。若某个时刻栈为空则说明当前区间是合法的,累加答案。

    为什么相同就直接弹出呢?会不会当前的括号与之后的括号匹配呢?仔细想想发现二者都是合法的,不需要多次计算答案

    现在优化这个暴力,从1开始,对于两个位置$i,j(i<j)$,若栈内的元素相同,那么说明$[i+1,j]$这一段是一个合法的区间。于是我们考虑对于每个位置的栈内元素hash,用map$存储当前hash值出现的次数,每次累加答案就是了

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<iostream>
    #include<map>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    
    const int N=1e6+15;
    const ll P=19260817;
    ll tp,n,ans,now;
    ll sta[N];
    ull pin[N];
    char s[N];
    map<ull,ll> Hash;
    int main(){
        freopen("bracket.in","r",stdin);
        freopen("bracket.out","w",stdout);
        scanf("%s",s+1);
        n=strlen(s+1);
        pin[0]=1;
        for (int i=1;i<=n;i++) pin[i]=pin[i-1]*P;
        Hash[0]++;
        for (int i=1;i<=n;i++){
            ll x=s[i]-'a'+1;//注意这里需要+1 
            sta[++tp]=x;
            now=now+pin[tp]*sta[tp];
            if (tp>=2&&sta[tp]==sta[tp-1]){
                now=now-pin[tp]*sta[tp]-pin[tp-1]*sta[tp-1];
                tp-=2;
            }
            ans+=Hash[now];
            Hash[now]++;
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    个人总结
    找水王
    nabcd需求分析
    四则运算最终篇-网页版四则运算
    第一次冲刺--个人工作总结02
    第一次冲刺--个人工作总结01
    组队APP功能点定点NABCD分析
    水王
    软件工程结对作业01
    个人工作总结06
  • 原文地址:https://www.cnblogs.com/xxzh/p/9824062.html
Copyright © 2011-2022 走看看