1. 程式人生 > >JZOJ5893. 【NOIP2018模擬10.4】括號序列

JZOJ5893. 【NOIP2018模擬10.4】括號序列

在這裡插入圖片描述 在這裡插入圖片描述

題解

維護一個棧,如果這個棧為空,就得到了一個答案。 考慮到如果某兩個位置棧裡面完全一樣,這也可以說明他們兩個之間的棧裡面是沒有任何元素。 於是可以用一個雜湊值來表示一個棧裡面的元素。

code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define N 1000003
#define ll long long
#define G getchar
using namespace std;

const ll mo=123456787654321;
const int w=31,M=10000007; 
int n,g[M],z[N],top,t;
ll h[M],s[N],ans;
char ch;

int hash(ll s)
{
	int x=s%M;
	for(;h[x]!=0 && h[x]!=s;x=x%M+1);
	return x;
}

int main()
{
	freopen("bracket.in","r",stdin);
	freopen("bracket.out","w",stdout);
	
	for(ch=G();ch<'a' && ch>'z';ch=G());
	for(n=0;'a'<=ch && ch<='z';ch=G())
	{
		t=ch-'a'+1;
		if(t==z[top])top--;
			else z[++top]=t,s[top]=(s[top-1]*w+t)%mo;
		if(top==0)ans++;
		t=hash(s[top]);h[t]=s[top];ans=ans+g[t];g[t]++;
	}
	
	printf("%lld",ans);
	
	return 0;
}