Codeforces964 C. Alternating Sum

题目链接:点击打开链接

题目大意:给一个序列只含'-'和 '+',长度为K,扩展成长度N+1(k为循环节长度),一个算式,(a +b)^n,去掉组合数,该位置的符号如果是+则为正,反之为负,求结果%mod的值(一定为正)。(这写的什么东西啊!)

解题思路:先求出前k个加起来的ans,这时候可以想到用等比数列来求后面的, 公比q = (b ^k)/(a ^ k),由等比数列的前n项和公式得到最终答案就是ans * (q ^ times - 1) * (q - 1) 的逆元

注意特判一下q == 1的时候的情况

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#define FAST ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
const int maxn = (int)1e5 + 5;
const ll mod = (int)1e9 + 9;
using namespace std;

ll quickpow(ll x, ll y){
	ll res = 1;
	while(y){
		if(y & 1) res = (res * x) % mod;
		y >>= 1;
		x = (x * x) % mod;
	}
	return res % mod;
}

char s[maxn];

int main()
{
	FAST;
	int n, a, b, k;
	scanf("%d %d %d %d", &n, &a, &b, &k);
	ll times = (n + 1) / k;
	scanf("%s", s);
	ll ans = 0;
	for(int i = 0; i < k; i++){
		if(s[i] == '-')	ans = (ans - quickpow(a, n-i) * quickpow(b, i) % mod + mod) % mod;
		else ans = (ans + quickpow(a, n-i) * quickpow(b, i) % mod + mod) % mod;
	}
	ll t = quickpow(b, k) * quickpow(a, k * (mod - 2)) % mod;
	if(t == 1){
		ans = ans * times % mod;
	}
	else{
		ans = ans * (quickpow(t, times) - 1) % mod * quickpow(t - 1, mod - 2) % mod;
	}
	cout << ans << endl;
	return 0;
}
over

猜你喜欢

转载自blog.csdn.net/swunhj/article/details/79995726