传送门
我们在建树的时候求出每个节点的哈希值
哈希函数你就乱搞一下
反正出题人不会来卡你哈希
#include<map>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1000005
#define pa pair<int,pair<int,int> >
#define mk make_pair
using namespace std;
char s[N*2];
int n,x,nx,cnt,tot=1,tmp,mx;
int f[N],dep[N],ch[N][3],sum[N];
map<pa,int> mp;
vector<int> ans[N];
int main(){
scanf("%s",s+1);
n=strlen(s+1)/2;
x=0;
mp[mk(0,mk(0,0))]=1;
for (int i=1;i<=2*n;i++){
if (s[i]=='('){
nx=++cnt;
f[nx]=x;
x=nx;
}
else{
if (ch[x][0]>ch[x][1]) swap(ch[x][0],ch[x][1]);
if (ch[x][0]>ch[x][2]) swap(ch[x][0],ch[x][2]);
if (ch[x][1]>ch[x][2]) swap(ch[x][1],ch[x][2]);
pa tmp=mk(ch[x][0],mk(ch[x][1],ch[x][2]));
if (!mp.count(tmp)) mp[tmp]=++tot;
ans[dep[x]].push_back(mp[tmp]);
mx=max(mx,dep[x]);
dep[f[x]]=max(dep[f[x]],dep[x]+1);
ch[f[x]][sum[f[x]]++]=mp[tmp];
x=f[x];
}
}
for (int i=0;i<=mx;i++){
tmp=1;
sort(ans[i].begin(),ans[i].end());
for (int j=1;j<ans[i].size();j++)
if (ans[i][j]!=ans[i][j-1]) tmp++;
printf("%d\n",tmp);
}
}