题意:
给你一棵树,问你有多少个组合的相似;
相似是a结点的子树和b结点的子树的每一层的结点数相等;
思路:
HASH来搞;
主要也没学过散列表,以及一个散列函数的构造;
其实看下面程序很简单,手跑案例就可以发现,每个结点有:a*pri^b,系数a就是在该节点下的b层结点个数。
暂时只理解到这个层面上,以后能用这个思想再用吧;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
const int mod=1e9+7;
const double eps=1e-8;
const int inf=0x3f3f3f3f;
const double pi=acos(-1.0);
//LL powmod(LL a,LL b) {LL res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ULL pri;
map<ULL,LL>p;
VI g[100010];
ULL dfs(int x){
int m=SZ(g[x]);
ULL ans=1;
for(int i=0;i<m;i++){
ans+=dfs(g[x][i])*pri;
}
p[ans]++;
return ans;
}
int main()
{
pri=mod;
map<ULL,LL>::iterator it;
int n,u,v;
cin>>n;
for(int i=1;i<n;i++){
cin>>u>>v;
g[u].pb(v);
}
dfs(1);
LL ans=0;
for(it=p.begin();it!=p.end();it++){
LL a=(*it).se;
ans+=a*(a-1)/2;
}
cout<<ans<<endl;
return 0;
}