Input file: commonants.in
Output file: commonants.out
Time Limit : 0.5 seconds
Memory Limit: 512 megabytesc++
最近公共祖先$\text{(Lowest Common Ancestor,LCA)}$是指在一個樹中同時擁有給定的兩個點做爲後
代的最深的節點。
爲了學習最近公共祖先,你獲得了一個層數爲$n+1$的滿二叉樹,其中根節點的深度爲$0$,其餘節點的深度爲父節點的深度$+1$。你須要求出二叉樹上全部點對 $\texttt{(i,j)}$,($i$,$j$能夠相等,也能夠$i > j$)的最近公共祖先的深度之和對$10^9+7$取模後的結果。學習
一行一個整數$n$。code
一行一個整數表示全部點對 $\texttt{(i,j)}$,($i$,$j$能夠相等,也能夠$i > j$)的最近公共祖先的深度之和對$10^9+7$取模後的結果。blog
$\texttt{input#1}$
2get
$\texttt{input#2}$
19260817input
$\texttt{output#1}$
22it
$\texttt{output#2}$
108973412class
樣例$1$解釋:
file
樹一共有$7$個節點(一個根節點和兩個子節點),其中 $\texttt{(4,4),(5,5),(6,6),(7,7)}$ 共$4$對的最近公共祖先深度爲$2$,$\texttt{(4,2),(2,4),(5,2),(2,5),(5,4),(4,5),(2,2),(6,3),(3,6),(3,7),(7,3),(6,7),}$$\texttt{(7,6),(3,3)}$共$14$對最近公共祖先深度是$1$,其餘的點對最近公共祖先深度爲$0$,因此答案爲$22$。二叉樹
對於$20%$的數據,$n \le 10$。
對於$50%$的數據,$n \le 10^6$ 。
對於$100%$的數據,$1 \le n \le 10^9$ 。
對於一顆有$n$層的滿二叉樹很顯然符合如下幾點
1.第$i$層的點的個數爲$2^i$。
2.以第$i$層的點爲根節點的子樹大小爲$2^{n-i+1}-1$。
3.以第$i$層的點爲$\text{LCA}$的點對個數爲$2^{2n-i+1}-2^i$
觀察上面的圖(好醜),很明顯$1,2$都是對的。
對於一顆以第$i$層的節點爲根的子樹:
①它的左子樹與右子樹上的點的$\text{LCA}$都爲根節點。因此點對個數爲
$$\LARGE\frac{2^{n-i+1}-2}{2} \times \frac{2^{n-i+1}-2}{2}$$
$$\LARGE= (2^{n-i}-1) \times (2^{n-i}-1)$$
$$\LARGE= 2^{2n-2i}-2^{n-i+1}+1$$
②這棵子樹的左子樹與根節點的$\text{LCA}$都爲根節點。右子樹也是。因此有$2^{n-i+1}-2$對點。
③根節點與根節點的$\text{LCA}$也是根節點,點對個數爲1。
點對$\texttt{(u,v)}$與點對$\texttt{(v,u)}$在$u \neq v$時是兩個不一樣的點對。
因此將上述①②相加乘二再加③就是以子樹根節點爲$\text{LCA}$的點對的數量爲:
$$\LARGE 2^{2n-2i+1}-1$$
由於第$i$層的點的個數爲$2^i$。因此以第$i$層的點爲$\text{LCA}$的點對個數爲:
$$\LARGE 2^{2n-i+1}-2^i$$
由於一共有$n+1$層,從$0-n$層,因此答案爲:
$$\LARGE \sum_{i=0}^{n} (2^{2n-i+1}-2^i) \times i$$
$$\LARGE =\sum_{i=0}^{n} i \times 2^{2n-i+1}-i \times 2^i$$
但這樣複雜度爲$\Theta (nlog_n)$過不了。。將上面的式子展開:
$$\LARGE \sum_{i=0}^{n} i \times 2^{2n-i+1} - \sum_{i=0}^{n} i \times 2^i$$
$$\LARGE T_n=\sum_{i=0}^{n} i \times 2^{2n-i+1}$$
$$\LARGE =2^{2n} + 2 \times 2^{2n-1} + 3 \times 2^{2n-2}+...+n \times 2^{n+1}$$
$$\LARGE 2T_n=2^{2n+1} + 2 \times 2^{2n} + 3 \times 2^{2n-1}+...+n \times 2^{n+2}$$
$$\Large 2T_n-T_n=2^{2n+1} + 2^{2n} + 2^{2n-1}+...+2^{n+2} - n \times 2^{n+1}$$
$$\LARGE T_n=2^{2n+1} + 2^{2n} + 2^{2n-1}+...+2^{n+2} - n \times 2^{n+1}$$
很明顯前$n$項爲等比數列,利用等比數列求和公式能夠很快求出。
$$\LARGE T_n=\sum_{i=0}^{n} i \times 2^i$$
$$\LARGE =2 + 2 \times 2^2 + 3 \times 2^3 +...+ n \times 2^n$$
$$\LARGE 2T_n=2^2 + 2 \times 2^3 + 3 \times 2^4 + ... + n \times 2^{n+1}$$
$$\LARGE T_n-2T_n=2 + 2^2 + 2^3 +...+2^n- n \times 2^{n+1}$$
很明顯也是等比數列。將這兩個相加就是答案了。
快速冪是$log$。因此複雜度是$\Theta(log_n)$
#include<bits/stdc++.h> typedef long long ll; ll n; const ll mod=1000000007; inline void read(ll &T) { ll x=0;bool f=0;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=!f;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} T=f?-x:x; } inline ll qpow(ll a,ll b) { ll ans=1,base=a; while(b) { if(b&1) ans=(ans*base)%mod; base=(base*base)%mod; b>>=1; } return ans%mod; } int main() { read(n); ll qwq=(((2*qpow(2,2*n+1))%mod-qpow(2,n+2)+5*mod)%mod-n*qpow(2,n+1)+5*mod)%mod; ll qaq=((((2*qpow(2,n))%mod)-2+5*mod)%mod-n*qpow(2,n+1)+5*mod)%mod; //std::cout<<qwq<<'\n'<<qaq<<'\n'; std::cout<<(qwq+qaq+5*mod)%mod;//加上一個模數再取模是爲了處理負數的狀況 return 0; }