jzoj5928

版权声明:本博客為本人嘔心瀝血之作,未經允許禁止轉載! https://blog.csdn.net/qq_39529862/article/details/83687211

tj:題解裡公式是錯的
我們可以考慮每一個節點[a,a+2^b-1]對答案的貢獻
則當這個節點是左兒子時,貢獻為2^b
是右兒子時,貢獻為 2 n a 2 b + 1 2^n-a-2^b+1
左兒子的公式為2^(n-2)n(n+1)
右兒子需要通過等比數列化簡。為 ( 2 ( n 1 ) + 1 ) ( ( n 1 ) 2 n + 1 ) 2 ( n 2 ) n ( n + 1 ) (2^(n-1)+1)*((n-1)*2^n+1)-2^(n-2)*n*(n+1)
然後由於每一個節點作為左端點和右端點貢獻相等,所以要乘2
最終答案為 ( ( 2 ( n 1 ) + 1 ) ( ( n 1 ) 2 n + 1 ) ) / ( 2 ( n 1 ) ( 2 n + 1 ) ) ((2^(n-1)+1)*((n-1)*2^n+1))/(2^(n-1)*(2^n+1))
代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mo 1000000007ll
ll n;
ll qp(ll x,ll y){
	if(!y)return 1;
	if(y==1)return x%mo;
	ll r=qp(x,y/2);
	if(y&1)return r*r%mo*x%mo;
	return r*r%mo;
}
int main(){
	freopen("A.in","r",stdin);
	freopen("A.out","w",stdout);
	scanf("%lld",&n);
	ll ans1=qp(2ll,n-1ll);
	ans1=(ans1+1ll)%mo;
	ll ans2=(n-1ll+mo)%mo;
	ans2=(ans2*qp(2ll,n))%mo;
	ans2=(ans2+1ll)%mo;
	ll ans3=ans1*ans2%mo;
	ll ans4=qp(2ll,n-2ll);
	ans4=ans4*(qp(2ll,n)+1ll)%mo;
	ll ans5=qp(ans4,mo-2ll);
	printf("%lld\n",ans3*ans5%mo);
}

猜你喜欢

转载自blog.csdn.net/qq_39529862/article/details/83687211