链接:https://www.nowcoder.com/acm/contest/136/J
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
洋灰是一种建筑材料,常用来筑桥搭建高层建筑,又称,水泥、混凝土。
WHZ有很多铸造成三角形的洋灰块,他想把这些洋灰三角按照一定的规律放到摆成一排的n个格子里,其中第i个格子放入的洋灰三角数量是前一个格子的k倍再多p个,特殊地,第一个格子里放1个。
WHZ想知道把这n个格子铺满需要多少洋灰三角。
输入描述:
第一行有3个正整数n,k,p。
输出描述:
输出一行,一个正整数,表示按照要求铺满n个格子需要多少洋灰三角,由于输出数据过大,你只需要输出答案模1000000007(1e9+7)后的结果即可。
示例1
输入
复制
3 1 1
输出
复制
6
说明
洋灰三角铺法:1 2 3,总计6个
示例2
输入
复制
3 2 2
输出
复制
15
说明
洋灰三角铺法:1 4 10,总计15个
示例3
输入
复制
3 3 3
输出
复制
28
说明
洋灰三角铺法:1 6 21,总计28个
备注:
对于100%的测试数据:
1 ≤ n ≤ 1000000000
1 ≤ k,p ≤ 1000
思路:
1、若k等于1,则数列为:1,2p,3p,…np,等差数列。Sn=n+n*(n-1)*p/2
2、若k不为1,则数列为:an=k*a(n-1)+p,用初中还是高中学的构造等比数列的方法(忘完啦)构造等比数列。
an+t=k(a(n-1)+p/k+t/k) ==> t=p/k+t/k ==> t=p/(k-1)
所以:an+p/(k-1)=k(a(n-1)+p/(k-1)),所以bn=an+p/(k-1)是等比数列
Sb=b1*(1-k^n)/(1-k)=Sa+n*p/(k-1)
Sa=(1+p/(k-1))*(1-k^n)/(1-k)-n*p/(k-1)
Sa=(k^n*(k-1+p)-k*(1+n*p)+p*(n-1)+1)/(k-1)^2
然后用:快速幂+逆元
代码如下:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
const int mod=1e9+7;
ll mod_pow(ll a,ll b){
ll res=1;
while(b){
if(b&1)res=(res*a)%mod;
b>>=1;
a=(a*a)%mod;
}
return res;
}
int main(){
ll n,k,p;
while(scanf("%d%d%d",&n,&k,&p)!=EOF){
ll ans=0;
if(k==1)ans=(n+n*(n-1)*p/2)%mod;
else {
ll s=mod_pow(k,n)*(k-1+p)-(p*n+1)*k+p*(n-1)+1;
s=(s%mod+mod)%mod;
ll x=(mod_pow((k-1)*(k-1),mod-2))%mod;
ans=(s*x)%mod;
}
printf("%lld\n",ans%mod);
}
}