1681 公共祖先

1681 公共祖先

Description

有一个庞大的家族,共n人。已知这n个人的祖辈关系正好形成树形结构(即父亲向儿子连边)。
在另一个未知的平行宇宙,这n人的祖辈关系仍然是树形结构,但他们相互之间的关系却完全不同了,原来的祖先可能变成了后代,后代变成的同辈……
两个人的亲密度定义为在这两个平行宇宙有多少人一直是他们的公共祖先。
整个家族的亲密度定义为任意两个人亲密度的总和。

Input

第一行一个数n(1<=n<=100000)
接下来n-1行每行两个数x,y表示在第一个平行宇宙x是y的父亲。
接下来n-1行每行两个数x,y表示在第二个平行宇宙x是y的父亲。

Output

一个数,表示整个家族的亲密度。

Input example

5
1 3
3 5
5 4
4 2
1 2
1 3
3 4
1 5

Output example

6

Solution

很神奇的数据结构题,首先,我们先dfs便历第一棵树,记录每个点的入时间戳和出时间戳(这点和tarjan类似),对于第二棵树,我们也进行一遍dfs,对于每一个节点u,我们先记录在第二棵树上,不包含u这个节点的子树时,有多少节点在u所包含的时间戳里出现过,因为出现过就知道这个点所覆盖的时间戳一定不是以u为祖先了,之后我们来便历第二棵树中u的子树,并在便历完之后重新统计有多少个节点在u所包含的时间戳里出现过,两次答案相减,便是两棵子树中都以u为祖先的节点数,设这个差为sum,则这个节点u对答案的贡献为(sum-1)*(sum-2),对于统计u所包含的时间戳中的结点个数,我们可以用树状数组来维护,代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
vector <int> edge[100010];
vector <int> pic[100010];
long long tree[10000000];
struct node{
    int in,out;
}dfn[100010];
int cnt,In[100010],n;
long long ans;
int lowbit(int x){
    return x&(-x);
}
void dfs1(int u,int fa){
    dfn[u].in=++cnt;
    for (int i=0;i<edge[u].size();i++){
        int v=edge[u][i];
        if (v==fa) continue;
        dfs1(v,u);
    }
    dfn[u].out=cnt;
}
long long query(int x){
    long long ans=0;
    for (int i=x;i;i-=lowbit(i)){
        ans+=tree[i];
    }
    return ans;
}
void add(int x,int val){
    for (int i=x;i<=n;i+=lowbit(i)){
        tree[i]+=val;
    } 
}
void dfs2(int u,int fa){
    long long sum=query(dfn[u].out)-query(dfn[u].in-1);
    add(dfn[u].in,1);
    for (int i=0;i<pic[u].size();i++){
        int v=pic[u][i];
        if (v==fa) continue;
        dfs2(v,u);
    }
    sum=query(dfn[u].out)-query(dfn[u].in-1)-sum-1;
    ans+=(sum-1)*sum/2;
}
int main(){
    scanf("%d",&n);
    for (int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        edge[u].push_back(v);
        In[v]++;
    }
    for (int i=1;i<=n;i++)
        if (!In[i]) dfs1(i,-1);
    memset(In,0,sizeof(In));
    for (int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        pic[u].push_back(v);
        In[v]++;
    }
    for (int i=1;i<=n;i++)
        if (!In[i]) dfs2(i,-1);
    printf("%lld\n",ans);
    return 0;
}
内容概要:报告《细分车市洞察报告2025》指出,2025至2028年中国乘用车细分市场经历剧烈演变,入门级车市持续萎缩,紧凑型轿车与小型轿车份额大幅下滑,而紧凑型SUV、中型SUV等中高端车型崛起。2021至2026年,中国车市将呈现“向上+多元”主旋律,受增换购、中年化、女性化和消费升级等趋势驱动,主流价区将由9-25万元上移至15-35万元。微型车因宏光MINI EV带动实现触底反弹,小型SUV面临转型压力,紧凑型SUV有望成为“第一车市”,中型SUV和中大型SUV成为新蓝海,MPV加速家用化,皮卡市场则需通过“破圈”实现突破。报告建议车企构建“向上+多元”产品体系,积极布局中高端及细分市场。; 适合人群:汽车制造商、经销商、行业分析师、市场研究人员及相关产业链从业者。; 使用场景及目标:①了解中国车市细分结构的历史演变与未来趋势;②把握增换购、中年化、女性化等核心驱动因素对各细分市场的影响;③制定针对中型SUV、高端MPV、皮卡等新兴蓝海市场的战略布局;④优化产品定位,实现从入门级向中高端、从单一功能向多元化场景的转型升级。; 阅读建议:本报告基于大量终端销量数据与用户调研,分析深入,建议结合图表与数据交叉验证,重点关注各细分市场的用户结构变化与竞争格局演变,用于指导产品规划与市场策略制定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值