51nod1709复杂度分析

题解:

注意到,如果第j位有贡献,那么从i往上跳2^j,然后不能再跳超过2^j。 
因此可以考虑倍增。

代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=100233,M=N<<1;
struct zs{int too,pre;}e[N<<1];
int tot,last[N],fa[N][18],fae[N][18],num[N],pos[N],TIM,sz[N];
ll sum[N],sume[maxn<<1],ans;
int k,n,m,ra,fh;
char rx;
inline int read()
{
    rx=getchar(),ra=0,fh=1;
    while((rx<‘0‘||rx>‘9‘)&&rx!=‘-‘)rx=getchar();
    if(rx==‘-‘)fh=-1,rx=getchar();
    while(rx>=‘0‘&&rx<=‘9‘)
     ra=ra*10+rx-48,rx=getchar();return ra*fh;
}
void dfs(int x)
{
    int to;
    pos[++TIM]=x;sz[x]=num[x]=1;
    for(int i=1;i<18;i++)
     fa[x][i]=fa[fa[x][i-1]][i-1],
     fae[x][i]=fae[fa[x][i-1]][i-1];
    for(int i=last[x];i;i=e[i].pre)
     if((to=e[i].too)!=fa[x][0])
      fa[to][0]=x,fae[to][0]=i,dfs(to),sz[x]+=sz[to];
}
inline void DFS(int x)
{
    register int i,to;
    for(i=last[x];i;i=e[i].pre)if((to=e[i].too)!=fa[x][0])
        ans+=1ll*sume[i]*(sz[x]-sz[to]),DFS(to);
}
void insert(int a,int b)
{
    e[++tot].too=b,e[tot].pre=last[a],last[a]=tot,
    e[++tot].too=a,e[tot].pre=last[b],last[b]=tot;
}
int main()
{
    n=read();
    for(int i=1;i<n;i++)insert(read(),read());
    dfs(1);
    int f;
    for(int j=0;j<18;j++)
     for(int i=1;i<=n;i++)
      if((f=fa[k=pos[i]][j]))
       num[f]+=num[k],sum[f]+=num[k]+sum[k],
       sume[fae[k][j]]+=num[k]+sum[k];
    DFS(1),printf("%lld\n",ans);
}
时间: 2024-10-18 12:28:17

51nod1709复杂度分析的相关文章

[51nod1709]复杂度分析

给出一棵n个点的树(以1号点为根),定义dep[i]为点i到根路径上点的个数.众所周知,树上最近公共祖先问题可以用倍增算法解决.现在我们需要算出这个算法精确的复杂度.我们定义计算点i和点j最近公共组先的精确复杂度为bit[dep[i]-dep[lca(i,j)]]+bit[dep[j]-dep[lca(i,j)]](bit[i]表示i在二进制表示下有多少个1,lca(i,j)表示点i和点j的最近公共祖先).为了计算平均所需的复杂度为多少,请你帮忙计算任意两点计算最近公共组先所需复杂度的总和.即计

51nod 1709 复杂度分析

51nod 1709 复杂度分析 考虑定义 $ F(x) $ 为 \(x\) 为根的子树所有点与 $ x $ 的深度差(其实就是 $ x $ 到每个子树内点的距离)的 1 的个数和. 注意,$ F(x) $ 的值不是答案,但是只需要一点树形dp的基础内容就可以变成要求的答案. 对于一个点 $ u $ , 考虑它的一个儿子 $ v $ , 我们此时已经计算出了 $ F( v ) $ 的值那么怎么统计 $ v $中所有点对于 $ u $ 的贡献呢?首先考虑 $ F(v) $ 的变化,由于当前的点 $

算法录 之 复杂度分析。

一个算法的复杂度可以说也就是一个算法的效率,一般来说分为时间复杂度和空间复杂度... 注意接下来说的均是比较YY的,适用与ACM等不需严格分析只需要大致范围的地方,至于严格的算法复杂度分析的那些数学证明,主定理什么的在<算法导论>这本书上有十分详细的讲解,网上应该也会有人写过,这里就不多说了(其实,是我不会而已o(╯□╰)o...). — 到底啥是复杂度呢?先来个栗子. 小明有10个苹果,有一天他饿了,然后准备吃掉一个苹果,但是小明有中二病,他要吃里面重量最大的那个,于是...他需要一个找到那

相似度分析的地址

相似度分析的,其中的分词可以采用HanLP即可: http://www.open-open.com/lib/view/open1421978002609.htm

Python 文本相似度分析

环境 Anaconda3 Python 3.6, Window 64bit 目的 利用 jieba 进行分词,关键词提取 利用gensim下面的corpora,models,similarities 进行语料库建立,模型tfidf算法,稀疏矩阵相似度分析 代码 # -*- coding: utf-8 -*- import jieba from gensim import corpora, models, similarities from collections import defaultdi

斐波那契数与二分法的递归与非递归算法及其复杂度分析

1. 什么是斐波那契数? 这里我借用百度百科上的解释:斐波那契数,亦称之为斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列.费波那西数列.费波拿契数.费氏数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.--在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*),用文字来说,就是斐波那契数列列由 0 和 1 开始,之后的斐波那契数列系数就由之前的两数相加.特别指出:0不是第一

递归算法复杂度分析方法

递归算法的复杂度分析方法. a.分析出复杂度公式(关于n的规模) b.求解这个公式 1.齐次 例如求fabonaci的第n项,f(n) = f(n-1)+f(n-2) => f(n)-f(n-1)-f(n-2)=0 =>特征方程:x^2-x-1=0 => x1,x2 => f(n)=a*x1n + b*x2n 2.master method T(n) = aT(n/b) + f(n) 3.采用分析树的方式 举个例子 f(n) = 2*f(n-1) + 1 1 1 ---------

杨辉三角(Pascal Triangle)的几种C语言实现及其复杂度分析

说明 本文给出杨辉三角的几种C语言实现,并简要分析典型方法的复杂度. 本文假定读者具备二项式定理.排列组合.求和等方面的数学知识. 一  基本概念 杨辉三角,又称贾宪三角.帕斯卡三角,是二项式系数在三角形中的一种几何排列.此处引用维基百科上的一张动态图以直观说明(原文链接http://zh.wikipedia.org/wiki/杨辉三角): 从上图可看出杨辉三角的几个显著特征: 1. 每行数值左右对称,且均为正整数. 2. 行数递增时,列数亦递增. 3. 除斜边上的1外,其余数值均等于其肩部两数

算法9-4:最大流算法复杂度分析

前面一节介绍了Ford-Fulkerson算法.那么这个算法是否一定能够在有限步骤内结束?要多少步骤呢? 这个问题的答案是,该算法确实能够在有限步骤之内结束,但是至于需要多少步骤,就要仔细分析. 为了分析问题,需要假定图中所有边的容量都是整数.但是有个严重的问题,比如下图中,如果使用Ford-Fulkerson算法,需要迭代200次才能结束. 首先将所有边的容量都初始化为0. 第一次迭代和第二次迭代之后,两条边各增加了1. 到最后200次迭代之后整个算法才结束. 这还不算最坏的情况.因为整数最多