給兩棵樹 問對於每對頂點 有多少除這兩個點之外的點 在這兩棵樹上都是這兩個點的公共祖先
考慮每個點的貢獻 對於乙個點 其子樹在兩棵樹上的有兩個dfs序 就看這兩個序列有多少數是相同的 c(n,2)一下即可
至於查詢兩個序列的兩個區間有所少數是相同的 主席樹搞一下就行 這有個這型別的裸題 先把這個做明白再看這道題
#include using namespace std;
typedef long long ll;
const int maxn=1e5+10;
struct node1
;struct node2
;node1 edge1[maxn],edge2[maxn];
node2 tree[20*maxn];
int book[maxn],first1[maxn],first2[maxn],mp1[maxn],mpp1[maxn],sum1[maxn],mp2[maxn],mpp2[maxn],sum2[maxn],root[maxn];
int n,q,num,r1,r2;
void addedge(node1 *edge,int *first,int u,int v)
void dfs(node1 *edge,int *first,int *mp,int *mpp,int *sum,int cur)
}void pushup(int cur)
int build(int l,int r)
int update(int rot,int tar,int l,int r)
m=(l+r)/2;
if(tar<=m) tree[cur].l=update(tree[rot].l,tar,l,m);
else tree[cur].r=update(tree[rot].r,tar,m+1,r);
pushup(cur);
return cur;
}int query(int lrot,int rrot,int pl,int pr,int l,int r)
res=0,m=(l+r)/2;
if(pl<=m) res+=query(tree[lrot].l,tree[rrot].l,pl,pr,l,m);
if(pr>m) res+=query(tree[lrot].r,tree[rrot].r,pl,pr,m+1,r);
return res;
}int main()
for(i=1;i<=n;i++) if(!book[i]) r1=i;
memset(first2,-1,sizeof(first2));
memset(book,0,sizeof(book));
num=0;
for(i=1;i<=n-1;i++)
for(i=1;i<=n;i++) if(!book[i]) r2=i;
num=0;
dfs(edge1,first1,mp1,mpp1,sum1,r1);
num=0;
dfs(edge2,first2,mp2,mpp2,sum2,r2);
/*for(i=1;i<=n;i++) printf("%d ",mp1[i]);
printf("\n");
for(i=1;i<=n;i++) printf("%d ",mp2[i]);
printf("\n");
*/num=0;
root[0]=build(1,n);
for(i=1;i<=n;i++)
ans=0;
for(i=1;i<=n;i++)
printf("%lld\n",ans);
return 0;
}
51nod 1681公共祖先
1681 公共祖先 有乙個龐大的家族,共n人。已知這n個人的祖輩關係正好形成樹形結構 即父親向兒子連邊 在另乙個未知的平行宇宙,這n人的祖輩關係仍然是樹形結構,但他們相互之間的關係卻完全不同了,原來的祖先可能變成了後代,後代變成的同輩 兩個人的親密度定義為在這兩個平行宇宙有多少人一直是他們的公共祖先...
51nod1681 公共祖先
1681 公共祖先 基準時間限制 1 秒 空間限制 131072 kb 分值 80 難度 5級演算法題 有乙個龐大的家族,共n人。已知這n個人的祖輩關係正好形成樹形結構 即父親向兒子連邊 在另乙個未知的平行宇宙,這n人的祖輩關係仍然是樹形結構,但他們相互之間的關係卻完全不同了,原來的祖先可能變成了後...
1681 公共祖先
有乙個龐大的家族,共n人。已知這n個人的祖輩關係正好形成樹形結構 即父親向兒子連邊 在另乙個未知的平行宇宙,這n人的祖輩關係仍然是樹形結構,但他們相互之間的關係卻完全不同了,原來的祖先可能變成了後代,後代變成的同輩 兩個人的親密度定義為在這兩個平行宇宙有多少人一直是他們的公共祖先。整個家族的親密度定...