主席树,让我有点懵逼。。。
//#include<bits/stdc++.h>
#include<stdio.h>
#include<cstring>
using namespace std;
void read(int&a){
char ch;while(!((ch=getchar())>='0')&&(ch<='9'));
a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10,a+=ch-'0';
}
const int MAXN=100100;
const int MAXM=2000100;
int LS[MAXN],LE[MAXN],RS[MAXN],RE[MAXN];
int tmp[MAXN],pos[MAXN],vis[MAXN],head[MAXN],root[MAXN];
int tot,sz;
struct Edge
{
int to,nxt;
}e[MAXN];
struct node
{
int l,r,c;
}tree[MAXM];
void init()
{
tot=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
}
void addedge(int u,int v)
{
e[tot].to=v;
e[tot].nxt=head[u];
head[u]=tot++;
}
void dfs(int u,int pre,int flag)
{
if(flag)
{
RS[u]=++sz;//标记u点的dfs序的起点
tmp[sz]=pos[u];//R树中,dfs序所代表的节点,在L树中的dfs序
}
else
{
LS[u]=++sz;//标记u点的dfs序的起点
pos[u]=sz;//L数中,标记u点的dfs序起点位置
}
for(int i=head[u];i!=-1;i=e[i].nxt)
{
if(e[i].to!=pre)
dfs(e[i].to,u,flag);
}
if(flag)
RE[u]=sz;//标记dfs序的终点。u及其子树的节点,在dfs序中的位置为[LS[u],LE[u]]
else
LE[u]=sz;
}
void update(int &rt,int l,int r,int num)
{
tree[++sz]=tree[rt];
rt=sz;
tree[rt].c++;
if(l==r)
return;
int mid=(l+r)>>1;
if(num<=mid)
update(tree[rt].l,l,mid,num);
else
update(tree[rt].r,mid+1,r,num);
}
int query(int x,int y,int L,int R,int l,int r)
{
if(L<=l&&R>=r)
return tree[y].c-tree[x].c;
int mid=(l+r)>>1;
int ret=0;
if(L<=mid)
ret+=query(tree[x].l,tree[y].l,L,R,l,mid);
if(R>mid)
ret+=query(tree[x].r,tree[y].r,L,R,mid+1,r);
return ret;
}
int main()
{
long long x,ans;
int n,u,v,rot,i;
while(~scanf("%d",&n))
{
tot=0;
init();
for(i=1;i<n;i++)
{
read(u);read(v);
addedge(u,v);
vis[v]=1;
}
sz=0;
for(i=1;i<=n;i++)
{
if(!vis[i])
{
rot=i;
break;
}
}
dfs(rot,0,0);
init();
for(i=1;i<n;i++)
{
read(u);read(v);
addedge(u,v);
vis[v]=1;
}
sz=0;
for(i=1;i<=n;i++)
{
if(!vis[i])
{
rot=i;
break;
}
}
dfs(rot,0,1);
root[0]=0;
sz=0;
memset(tree,0,sizeof(tree));
for(i=1;i<=n;i++)
{
root[i]=root[i-1];
update(root[i],1,n,tmp[i]);
}
ans=0;
for(i=1;i<=n;i++)
{
x=query(root[RS[i]-1],root[RE[i]],LS[i],LE[i],1,n);
ans+=(x-1)*(x-2)/2;
}
printf("%lld\n",ans);
}
}