• 2478. [HZOI 2016]简单的最近公共祖先


    ★☆   输入文件:easy_LCA.in   输出文件:easy_LCA.out   简单对比

    时间限制:2 s   内存限制:128 MB

    【题目描述】

    给定一棵有n个节点的有根树,根节点为1,每个节点有一个权值wi,求

    即求所有无序节点对的LCA的权值之和。

    树的节点编号为1~n,LCA表示两节点的最近公共祖先,即在它们的所有公共祖先中离根节点最远的节点。

    【输入格式】

    第一行一个整数n,表示节点数。

    第二行n个正整数,表示每个点的权值。

    以下n-1行每行两个整数x,y,表示树上有一条边连接节点x和节点y。

    【输出格式】

    一个整数,表示答案。

    【样例输入】

    3
    1 2 3
    1 2
    1 3

    【样例输出】

    9

    【数据范围与约定】

    对于30%的数据,n<=1000。

    对于60%的数据,n<=100000。

    对于100%的数据,1<=n<=1000000,0<wi<=1000000。

    【来源】

    HZOI 2016

    裸地lca竟然只过3点:

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    const int N=1000010;
    
    int head[N],deep[N],w[N],jump[N][25];
    int now=1,n,root=1;
    long long answer;
    struct node{
    	int u,v,nxt;
    }E[N];
    
    inline int read()
    {
    	int x=0;char c=getchar();
    	while(c<'0'||c>'9')c=getchar();
    	while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
    	return x;
    }
    
    inline void add(int u,int v)
    {
    	E[now].v=v;
    	E[now].nxt=head[u];
    	head[u]=now++;
    }
    
    void make_deep(int root)
    {
    	for(int i=head[root];~i;i=E[i].nxt)
    		if(!deep[E[i].v])
    			deep[E[i].v]=deep[root]+1,
    			jump[E[i].v][0]=root,
    			make_deep(E[i].v);
    }
    
    inline void make_jump()
    {
    	for(int i=1;i<=19;i++)
    		for(int j=1;j<=n;j++)
    			jump[j][i]=jump[jump[j][i-1]][i-1];
    }
    
    inline int lca(int x,int y)
    {
    	if(deep[x]<deep[y])
    		swap(x,y);
    	for(int i=19;i>=0;i--)
    		if(deep[jump[x][i]]>=deep[y])
    			x=jump[x][i];
    	if(x==y)
    		return x;
    	for(int i=19;i>=0;i--)
    		if(jump[x][i]!=jump[y][i])
    			x=jump[x][i],
    			y=jump[y][i];
    	return jump[x][0];
    }
    
    int main()
    {
    	freopen("easy_LCA4.in","r",stdin);
    	freopen("easy=_LCA.out","w",stdout);
    	n=read();
    	for(int i=1;i<=n;i++)
    		head[i]=-1,w[i]=read();
    	for(int i=1;i<n;i++)
    	{
    		int u=read(),v=read();
    		add(u,v);
    		add(v,u);
    	}
    	deep[root]=1;
    	make_deep(root);
    	make_jump();
    	
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=i;j++)
    			answer+=w[lca(i,j)];
    	
    	printf("%lld",answer);
    	return 0;
    }
    

      

    #include<cstdio>
    #include<cstring>
    
    #define Cu fclose(stdin);fclose(stdout);return 0;
    #define Begin freopen("easy_LCA.in","r",stdin);freopen("easy_LCA.out","w",stdout);chul();Cu;
    
    using namespace std;
    const int maxn=1000010;
    
    int w[maxn],head[maxn],size[maxn],tim;
    long long ans=0;
    typedef long long ll;
    int fath[maxn];
    
    struct op{
    	int to,next;
    }r[maxn<<1];
    
    void insert(int fr,int to)
    {
    	tim++;
    	r[tim].to=to;
    	r[tim].next=head[fr];
    	head[fr]=tim;
    }
    
    void dfs(int rt)
    {
    	size[rt]=1;
    	int x=0,y;
    	for(int i=head[rt];i;i=r[i].next)
    	{
    		y=r[i].to;
    		if(fath[rt]==y)continue;
    			fath[y]=rt;
    		dfs(y);
    		ans+=(ll)size[rt]*size[y]*w[rt];
    		size[rt]+=size[y];
    	}
    }
    
    void chul()
    {
    	int n,s,t;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&w[i]);
    		ans+=w[i];
    	}
    	for(int i=1;i<n;i++)
    	{
    		scanf("%d%d",&s,&t);
    		insert(s,t);
    		insert(t,s);
    	}
    	dfs(1);
    	printf("%lld
    ",ans);
    }
    
    
    int main()
    {
    	Begin;
    }
    

      

  • 相关阅读:
    VMware workstation 创建共享盘
    VMware vSphere 创建共享盘
    pdksh 包
    oracle virtualbox 添加共享硬盘
    debian 8.2 dynamic add disk
    postgresql 9.1 下的 pg_dump 的初步研究
    postgresql pg_xlog_location_diff 函数
    postgresql 结束进程
    postgresql 加载参数文件
    postgresql 切换xlog日志
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7198747.html
Copyright © 2020-2023  润新知