思路:
一个点的有序对数目=它上一个点的有序对数目+到目前为止出现过的商品总数-这个点上一次出现时的有序对数目(避免重复计算),我们用一个pre数组记录一下上一个该商品出现时的商品数目,用一个vis数组记录一下一个商品是否出现过,回溯一下就即可
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=100010;
vector<int>vt[maxn];
int a[maxn];
ll per[maxn];
ll f[maxn];
int vis[maxn];
void dfs(int u,int fa,int cnt)
{
for(int i=0;i<vt[u].size();i++)
{
int v=vt[u][i];
if(!vis[a[u]])
{
cnt++;
}
vis[a[u]]++;
f[v]=f[u]+cnt-per[a[v]];
int temp=per[a[v]];
per[a[v]]=cnt;
dfs(v,u,cnt);
vis[a[u]]--;
if(vis[a[u]]==0)
{
cnt--;
}
per[a[v]]=temp;
}
}
int main()
{
int n;
while(cin>>n)
{
memset(vis,0,s