题目链接:https://vjudge.net/contest/174844#problem/J
题意: 给定N个 a,b,c 表示 每组有 a^b到 a^c, c-b+1个数,求每组取一个数相乘,所有可能的选取方法的乘积之和,对结果mod1000000007。
思路:先分析所有情况的乘积公式,很容易发现可以合并,然后问题就转变成了每组 a^b到 a^c的和的乘积。
求 a^b到 a^c的和 可以利用等比数列求和公式,( a^b-a^(c+1))/(1-a) ;
但是涉及到幂次方很大,需要用到快速幂取模,除法的取模就需要用到 逆元
这里快速幂的方法对我个人容易理解,但是逆元这里一直都是一个弱项,今天来攻克一下。
1.欧几里得算法的扩展 (逆元函数的参数为n,mod)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
ll pow_mod(ll a,ll b) // 快速幂取模
{
ll ans=1;
while (b)
{
if (b&1) ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
ll ext_gcd(ll a, ll b, ll &x, ll &y) //扩展欧几里得
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
ll d = ext_gcd(b, a % b, x, y);
ll tmp = x;
x = y;
y = tmp-a/b*y;
return d;
}
ll inv(ll a, ll mod) { // 逆元计算
ll x, y;
ext_gcd(a, mod, x, y);
return (x % mod + mod) % mod;
}
ll cal(int n,int x,int y)
{
if(n==1)
return (y-x+1)%mod;//特殊情况a-1=0
else
{
ll ab=pow_mod(n,x)%mod;//求首项
ll ac=(ab*(pow_mod(n,y-x+1)-1)%mod)%mod;
ll a_1=inv(n-1,mod);//求逆元
ll s=ac*a_1%mod;
return s;
}
}
int main()
{
int t,icase=0;
scanf("%d",&t);
while(t--)
{
ll n,a,b,c,sum=1;
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&a,&b,&c);
sum=sum*cal(a,b,c)%mod;
}
printf("Case #%d: %lld\n",++icase,sum);
}
}2.费马小定理(逆元函数的参数为 n ,mod-2)
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
ll pow_mod(ll a,ll n)
{
int t=1;
while(n>0)
{
if(n&1)
t=t*a%mod;
a=a*a%mod;
n>>=1;
}
return t;
}
ll cal(int n,int x,int y)
{
if(n==1)
return (y-x+1)%mod;//特殊情况a-1=0
else
{
ll ab=pow_mod(n,x)%mod;//求首项
ll ac=(ab*(pow_mod(n,y-x+1)-1)%mod)%mod;
ll a_1=pow_mod(n-1,mod-2)%mod;//求逆元
ll s=ac*a_1%mod;
return s;
}
}
int main()
{
int t,icase=0;
scanf("%d",&t);
while(t--)
{
ll n,a,b,c,sum=1;
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&a,&b,&c);
sum=sum*cal(a,b,c)%mod;
}
printf("Case #%d: %lld\n",++icase,sum);
}
}

本文介绍了一种求解特定组合问题的算法实现,通过快速幂取模与逆元计算解决大数运算难题,提供了两种逆元计算方法:扩展欧几里得算法和费马小定理。
1388

被折叠的 条评论
为什么被折叠?



