SDSC2018 Day2

$ \Rightarrow $ 戳我下载文件密码:apia
 

T1数学害死人啊,只写了T1要完蛋啦!!!w(゚Д゚)w
  ## Problem A. 最近公共祖先 (commonants.c/cpp/pas)

Input file: commonants.in
Output file: commonants.out
Time Limit : 0.5 seconds
Memory Limit: 512 megabytes
 

最近公共祖先(Lowest Common Ancestor,LCA)是指在一个树中同时拥有给定的两个点作为后 代的最深的节点。

为了学习最近公共祖先,你得到了一个层数为 $ n + 1 $ 的满二叉树,其中根节点的深度为 $ 0 $ ,其他 节点的深度为父节点的深度 $ +1 $ 。
你需要求出二叉树上所有点对 $ (i,j) $ ,$ (i,j $ 可以相等,也可以 $ i > j)$ 的最近公共祖先的深度之和对 $ 10^9 + 7 $ 取模后的结果。
 

Input

一行一个整数 $ n $ 。
 

Output

一行一个整数表示所有点对 $ (i,j),(i,j $ 可以相等,也可以 $ i > j)$ 的最近公共祖先的深度之和对 $ 10^9 + 7 $ 取模后的结果。
 

Examples

commonants.in commonants.out
2 22
19260817 108973412

 

Notes

样例 1 解释:

pic

树一共有 7 个节点(一个根节点和两个子节点),
其中 (4,4),(5,5),(6,6),(7,7) 共 4 对的最近公共祖先深度为 2,
(4,2),(2,4),(5,2),(2,5),(5,4),(4,5),(2,2),(6,3),(3,6),(3,7),(7,3),(6,7),(7,6),(3,3) 共 14 对最 近公共祖先深度是 1 ,
其他的点对最近公共祖先深度为 0 ,所以答案为 22 。

对于 20% 的数据,$ n ≤ 10 $ 。
对于 50% 的数据,$ n ≤ 10^6 $ 。
对于 100% 的数据,$ 1 ≤ n ≤ 10^9 $ 。

 

题解

  • 考虑每棵子树对答案的贡献。

  • 设当前层数为 $ i $ ,子树的大小(节点数量,包括子树根)为 $ 2^{n-i+1} $ ,该层有 $ 2^i $ 棵这样的子树。

  • 对于除子树根外,两棵子树的节点互相选择,$ lca$ 一定为子树根,贡献为 $ \frac{2^{n-i+1}-1}{2} \times \frac {2^{n-i+1}-1}{2} \times 2 $

  • 对于子树根来说,每个子节点与自己的 $ lca $ 一定也是自己,贡献为 $ (2^{n-i+1}-1) \times 2 \times i $

  • 对于整棵子树来说,自己和自己的 $ lca $ 也要贡献答案,所以设上述贡献的和为 $ tmp $ ,则这层的贡献为 $ (tmp+i)*2^i $

  • 整个式子是这样的 $ \sum_{i=1}^n ((\frac{2^{n-i+1}-1}{2} \times \frac {2^{n-i+1}-1}{2} \times 2 + (2^{n-i+1}-1) \times 2 \times i )+i)*2^i $
     

  • 化简(这个过程很艰难)得:$ \sum_{i=1}^n (2{2n-i+1}-2i) \times i $

  • 好的,熟悉的数学必修5时间到了!ヾ(•ω•`)o
     

\[S=2^{2n}-2^1+2 \times (2^{2n-1}-2^2) + 3 \times (2^{2n-2} - 2^3) + \dots + (n-1) \times (2^{n+1} - 2^{n-1}) + n \times (2^{n+1} - 2^n) \]

\[2S=2^{2n+1} - 2^2+ 2 \times (2^{2n}-2^3) + 3 \times (2^{2n-1} - 2^4) + \dots + (n-1) \times (2^{n+2} - 2^n) + n \times (2^{n+2} - 2^{n+1}) \]

 

  • 展开一、二式
     

\[S=2^{2n} - 2 \times 2^2 + 2\times 2^{2n-1} - 3 \times 2^3 + 3 \times 2^{2n-2} + \dots + n \times 2^{n+1} - n \times 2^n - 2^1 \]

\[2S=2 \times 2^{2n} - 2^2 + 3 \times 2^{2n-1} - 2 \times 2^3 + 4 \times 2^{2n-2} - \dots + n \times 2^{n+2} - n \times 2^{n+1} + 2^{2n+1} \]

 

  • 合并(这个过程也很艰难),我们可以发现式子就是(可能有误,未效验)
     

\[2S-S= \sum_{i=1}^n 2^i + \sum_{i=n+1}^{2n} 2^i - n \times 2^{n+1} \]

 

  • 最终的答案为:
     

\[ans = 2^{2n+2} + 2^{n+1} - (n+1) \times 2^{n+2} -2 \]

 

  • 直接使用快速幂即可

 

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define int unsigned long long
#define Mod 1000000007
int n,tot,ans;
int qpow(int k){
	int res=2,x=2; --k;
	while(k){
		if(k&1) res=res*x%Mod;
		x=x*x%Mod;
		k>>=1;
	}
	return res;
}
signed main(){
	freopen("commonants.in","r",stdin);
	freopen("commonants.out","w",stdout);
	scanf("%lld",&n);
	printf("%lld",((((qpow(2*n+2)%Mod+qpow(n+1)%Mod)%Mod-(n+1)*qpow(n+2)%Mod)+Mod)%Mod-2+Mod)%Mod);
	return 0;
}
posted @ 2018-09-18 19:55  potrem  阅读(262)  评论(0编辑  收藏  举报