背景:阿塔尼斯,达拉姆的大主教,在艾尔又一次沦陷之后指挥着星灵的最后一艘方舟舰:亚顿之矛。作为艾尔星灵数千年来的智慧结晶,亚顿之矛除了搭载了以太阳能碎片为核心的兵工厂之外,还配备了诸如汇聚射线、太阳能射线枪等威力强大的支援武器。而在这些武器中,最负盛名、也最让敌人胆寒的就是太阳轰炸。
太阳轰炸是一件威力巨大的对星球武器。在太阳轰炸开火时,亚顿之矛将聚集太阳能核心中的太阳能量,向目标坐标发射成百上千枚火焰飞弹。虽然这些火焰飞弹精准度较差,但太阳轰炸的高攻击频率仍然可以让地面上的敌人无法躲避,化为灰烬。
在这一次的行动中,阿塔尼斯的目标是一枚臭名昭著的虚空碎片。在俯视视角下,虚空碎片的投影是一个半径为 R1 的圆,太阳轰炸的攻击散布范围是一个半径为 R2 的圆。这两个圆的圆心均为原点 (0, 0)。太阳轰炸将射出 n 枚火焰飞弹,每一枚火焰飞弹等概率地落在攻击散布范围内每一个点上,所有火焰飞弹的落点相互独立。火焰飞弹的伤害范围是以落点为圆心,半径为 r 的圆。若火焰飞弹的伤害范围和虚空碎片的投影相交,则该枚火焰飞弹命中虚空碎片,造成 a 点伤害。若总伤害大于等于 h,则虚空碎片会被摧毁。
摧毁这枚虚空碎片对阿塔尼斯的战略部署非常重要,因此阿塔尼斯想要知道一次太阳轰炸能够摧毁这枚虚空碎片的概率。你需要输出答案对质数 109 + 7 取模的值。
Input
仅一行,包含六个整数 n, R1, R2, r, a, h (1 ≤ n ≤ 5 × 106, 1 ≤ R1, R2, r ≤ 108, 1 ≤ a, h ≤ 108),含义见题目描述。
Output
一个整数,表示答案。
Example
input
Copy
3 2 4 1 1 1
output
Copy
636962896
Note
答案对质数 109 + 7 取模的定义:设 M = 109 + 7,可以证明答案可表示为一个既约分数
,其中 p, q 均为整数且 q 模 M 不余 0。输出满足 0 ≤ x < M 且 x·q ≡ p ± od{M} 的整数 x。
上图对应了样例中 R1 = 2, R2 = 4, r = 1 的情况。其中红色的圆是虚空碎片的投影,蓝色的圆是太阳轰炸的攻击范围。A, B, C 是三R2这个圆是攻击范围,
假设:R1是目标,r是导弹的攻击半径,所以恰好不攻击到的范围就是导弹跟目标相切,这个时候距离就是R1 + r,个可能的落点,其中 A, C 命中虚空碎片,而 B 没有命中虚空碎片。
思路:
这个题总共有三种情况;
1: (h-1)/a+1>n,无解,直接输出0;
2:(R1+r)>=R2,就是无论怎么发射都会打在虚空碎片上,直接输出“1”;
3:
只要在这个范围以内的
都可以对目标造成伤害,导弹击中目标的概率就是,但是概率不能超过1,所以跟1取min,利用二项分布,
#include<bits/stdc++.h>
using namespace std;
const int N=5e6+10;
const int mod=1e9+7;
#define int long long
#define lmw ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int fact[N],infact[N];
int n,r1,r2,r,a,h;
inline int ksm(int x,int y){
x%=mod;
int res=1;
while(y){
if(y&1) res=res*x%mod;
x=x*x%mod;
y/=2;
}
return res%mod;
}
inline int C(int a,int b){
return fact[a]*infact[b]%mod*infact[a-b]%mod;
}
int lucas(int a,int b){
if(a<mod&&b<mod) return C(a,b);
return C(a%mod,b%mod)*lucas(a/mod,b/mod)%mod;
}
inline void unit(){
fact[0]=1;
for(int i=1;i<=n;i++){
fact[i]=fact[i-1]*i%mod;
}
infact[n]=ksm(fact[n],mod-2);
for(int i=n-1;i>=0;i--){
infact[i]=infact[i+1]*(i+1)%mod;
}
}
signed main(){
lmw;
cin>>n>>r1>>r2>>r>>a>>h;
// cin>>n;
unit();
// infact[5000000]=ksm(fact[5000000],mod-2)%mod;
// for(int i=4999999;i>=0;i--){
// infact[i]=infact[i+1]*(i+1)%mod;
// }
// cout<<infact[25]<<"\n";
int op=(h-1)/a+1;
// if(h%a!=0) op++;
if(n<op){
cout<<"0\n";
return 0;
}
else if(r1+r>=r2){
cout<<"1\n";
return 0;
}
int p=(r1+r)*(r1+r)%mod*ksm(r2*r2,mod-2)%mod;
int q=(r2*r2%mod-(r1+r)*(r1+r)%mod+mod)%mod*ksm(r2*r2,mod-2)%mod;
int pp=ksm(p,op);
int qq=ksm(q,n-op);
int sum=0;
for(int i=op;i<=n;i++){
// sum=(sum+infact[i]*ksm(r1+r,i*2)%mod*ksm((r2*r2-(r1+r)*(r1+r)+mod)%mod,(n-i)))%mod;
sum=(sum+C(n,i)*pp%mod*qq%mod)%mod;
pp=pp*p%mod;
qq=qq*ksm(q,mod-2)%mod;
}
// int m=ksm(r2*r2%mod,n)%mod;
cout<<sum<<"\n";
}
枚举导弹击中的次数,算一下概率就可以了。