<题目链接>

<转载于 >>>  >

题目大意:
给出一串n个数字,让你在这串数字中添加k个 ' + ' 号(添加后表达式合法),然后所有拆分所得的所有合法表达式之和。

解题分析:

首先,暴力的做法肯定是不可行的,复杂度必然爆炸。然后来考虑怎么求每个数字在最终结果里的贡献呢。我们这n个数字有n-1个空位置,来放置k个' + '号,不论哪一种放置方法,每个数字都要在这种情况里出现一次,但是出现时所充当的分位是不同的,这就是统计贡献的地方!再由于每个数字都是不同的单独的,所以单独考虑每个数字可能所成为的位数时不会出现重复。

第n位:只能充当某个数字的个位有C(n-1,k)种个位情况

第n-1位:能充当个位(加号必须放一个在它后面才它能成为个位),能充当十位(加号必须放一个在它后面的后面才能使他成为十位并且他和个位之间不能放置东西)   个位:C(n-2,k-1)    十位:C(n-2,k)

第n-2位:同理   个位:C(n-2,k-1)   十位:C(n-3,k-1)  百位:C(n-3,k)

.........

也就是说:

倒数第一位:贡献了C(n-1,k)次个位数

倒数第二位:贡献了C(n-2,k-1)次个位数,C(n-2,k)次十位数

倒数第三位:贡献了C(n-2,k-1)次个位数,C(n-3,k-1)次十位数,C(n-3,k)次百位数

倒数第四位:贡献了C(n-2,k-1)次个位数,C(n-3,k-1)次十位数,C(n-4,k-1)次百位数,C(n-4,k)次千位数

........

倒数第n位:贡献了C(n-2,k-1)次个位数,C(n-3,k-1)次十位数,C(n-4,k-1)次百位数,C(n-4,k)次千位数......C(n - n,k)次n位数

所以我们预处理一下组合数C(x,k-1)和C(x,k),类似求个前缀和就可以啦!

核心部分:

倒数第一位:C(n-1,k)*s[n]

倒数第二位:C(n-2,k-1)*s[n-1] + C(n-2,k)*10*s[n-1]

倒数第三位:(C(n-2,k-1) + C(n-3,k-1)*10)*s[n-2] + C(n-3,k)*100*s[n-2]

倒数第四位:(C(n-2,k-1) + C(n-3,k-1)*10 + C(n-4,k-1)*100)*s[n-3] + C(n-4,k)*1000*s[n-3]

...........

所以可以看出,每一位数字的前部分(红色)和是从第n位累和过来的,后部分(绿色)是单独处理的,所以我们可以从第n位,开始往前循环每一位到第一位,累前缀和求和即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
const int M = 1e5+;
const int mod = 1e9+;
using namespace std;
typedef long long ll;
ll fac[M],inv[M],sum[M],a[M];
char s[M];
int n,k;
ll ans,mult;
ll mod_pow(ll x,ll n){
x%=mod;
ll res = ;
while(n>){
if(n&) res = res*x%mod;
x = x*x%mod;
n>>=;
}
return res;
}
void init(){
inv[]=;fac[]=;
for(int i=;i<=n;i++){
fac[i] = (fac[i-]*i)%mod;
inv[i] = mod_pow(fac[i],mod-)%mod; //费马小定理预处理记录 i! 的逆元
}
}
ll C(ll n,ll m){
if(n<||m<) return ;
if(m>n) return ;
return (((fac[n]*inv[m])%mod)*inv[n-m])%mod; //计算组合数C(n,m), n!*(m!的逆元)*((n-m)!的逆元)
}
int main()
{
scanf("%d%d",&n,&k);
init();
scanf("%s",s+);
for(int i=;i<=n;i++)
a[i] = s[i]-'';
mult = ;
for(int i=n-;i>=;i--){
sum[i] = (sum[i+]+mult*C(i-,k-))%mod; //计算该数位为红色部分的贡献,因为红色部分这一位与这一位+1的贡献有关,所以可以求部分前缀和,简化计算
mult = (mult*)%mod;
}
mult = ;
for(int i=n;i>=k+;i--){
sum[i] = (sum[i]+C(i-,k)*mult)%mod;//计算该位数绿色部分的贡献
mult = (mult*)%mod;
}
ans = ;
for(int i=;i<=n;i++)
ans = (ans+sum[i]*a[i])%mod; //乘上每个位数上的数
printf("%lld\n",ans);
}

2018-10-09

Codeforces 521C (经典)组合数取模【逆元】的更多相关文章

  1. HDU 5698 大组合数取模(逆元)

    瞬间移动 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...

  2. 组合数取模Lucas定理及快速幂取模

    组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1)  , 此时较简单,在O(n2)可承受的情况下组合数的计算可以 ...

  3. [BZOJ 3129] [Sdoi2013] 方程 【容斥+组合数取模+中国剩余定理】

    题目链接:BZOJ - 3129 题目分析 使用隔板法的思想,如果没有任何限制条件,那么方案数就是 C(m - 1, n - 1). 如果有一个限制条件是 xi >= Ai ,那么我们就可以将 ...

  4. lucas定理解决大组合数取模

    LL MyPow(LL a, LL b) { LL ret = ; while (b) { ) ret = ret * a % MOD; a = a * a % MOD; b >>= ; ...

  5. 2015 ICL, Finals, Div. 1 Ceizenpok’s formula(组合数取模,扩展lucas定理)

    J. Ceizenpok’s formula time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  6. 组合数取模&&Lucas定理题集

    题集链接: https://cn.vjudge.net/contest/231988 解题之前请先了解组合数取模和Lucas定理 A : FZU-2020  输出组合数C(n, m) mod p (1 ...

  7. 排列组合+组合数取模 HDU 5894

    // 排列组合+组合数取模 HDU 5894 // 题意:n个座位不同,m个人去坐(人是一样的),每个人之间至少相隔k个座位问方案数 // 思路: // 定好m个人 相邻人之间k个座位 剩下就剩n-( ...

  8. hdu 3944 DP? 组合数取模(Lucas定理+预处理+帕斯卡公式优化)

    DP? Problem Description Figure 1 shows the Yang Hui Triangle. We number the row from top to bottom 0 ...

  9. BZOJ_2142_礼物_扩展lucas+组合数取模+CRT

    BZOJ_2142_礼物_扩展lucas+组合数取模 Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同 ...

随机推荐

  1. python 面向对象编程(初级篇)

    飞机票 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强...” 面向过程编程最 ...

  2. Confluence 6 Confluence 安装目录

    Confluence 安装的目录(Confluence Installation directory)定义的是 Confluence 是在那里进行安装的.这个目录有时候也被称为 Confluence ...

  3. js数组的实例方法sort() 排序方法的运用,不再只是.sort()

    1, sort() 不传回调函数的话,默认按照字母顺序(字符编码)的顺序进行排序. 2, sort() 通过传回调函数来控制从小到大的排序还是从大到小的排序: var arr = [1,23,5,6, ...

  4. flask 中orm关系映射 sqlalchemy的查询

    flask的orm框架(SQLAlchemy)-一对多查询以及多对多查询   一对多,多对多是什么? 一对多.例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级. 多对多.例如,学生与课 ...

  5. tensorflow(3):神经网络优化(ema,regularization)

    1.指数滑动平均 (ema) 描述滑动平均: with tf.control_dependencies([train_step,ema_op]) 将计算滑动平均与 训练过程绑在一起运行 train_o ...

  6. go的gin框架从请求中获取参数的方法

    前言: go语言的gin框架go里面比较好的一个web框架, github的start数超过了18000.可见此框架的可信度 如何获取请求中的参数 假如有这么一个请求: POST   /post/te ...

  7. Python 读写excel类

    #-*- coding: utf8 -*- import xlrd import xlwt from Public import GlobalClass def openexcel(path): tr ...

  8. windows下Qt播放flash

    Qt  版本:5.1.0 32bit 代码部分,参考1即可.配置发行时,需要将NPSWF32放在项目的plugins\目录中. 否则,可能找不到,导致无法运行. QWebSettings *setti ...

  9. Two Sum【LeetCode】

    Given an array of integers, return indices of the two numbers such that they add up to a specific ta ...

  10. 如果拷贝项目出现各种找不到文件的时候,基本就是没有标记,或者文件名的问题,Could not find resource mybatis.xml,解决方法

    Could not find resource mybatis.xml