<题目链接>

<转载于 >>>  >

题目大意:
给出一串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. 【MySql】join操作

    飞机票 飞机票 加油 INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录. LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录. RIGHT JOIN( ...

  2. Mybatis调用PostgreSQL存储过程实现数组入参传递

    注:本文来源于 < Mybatis调用PostgreSQL存储过程实现数组入参传递  > 前言 项目中用到了Mybatis调用PostgreSQL存储过程(自定义函数)相关操作,由于Pos ...

  3. Confluence 6 修改日志文件的目标位置

    在 log4j 中,一个输出被定义为 'appender'.希望修改 log 文件的目标,你需要停止 Confluence 然后修改设置 log4j.properties 日志配置文件的  'Logg ...

  4. jquery 的鼠标事件/淡入淡出/绑定

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  5. gnuradio 打包脚本

    #!/bin/sh echo "cd build" cd build echo "rm -rf **" rm -rf ** echo "cmake . ...

  6. phpstudy添加redis扩展

    操作系统   windows: 直接贴步骤记录下 一.      划重点,运行phpinfo(), 观察第四行 x86  好了记住这个 x86 三.    http://pecl.php.net/pa ...

  7. 字符串为空的比较 ==与equals() 区别(キ`゚Д゚´)!!基础很重要 !!!

    情况描述:我提交的代码,让老大审批了一次,讲真的,对于我来说受益匪浅,其中有一个印象很深的内容:一个字符串是否为空的判断,我以前敲代码一直都是这样写的,可是从来都没有意识到这个东西. 代码: if(s ...

  8. 常见的排序算法(直接插入&选择排序&二分查找排序)

    1.直接插入排序算法 源码: package com.DiYiZhang;/* 插入排序算法 * 如下进行的是插入,排序算法*/ public class InsertionSort {    pub ...

  9. 论文阅读笔记十六:DeconvNet:Learning Deconvolution Network for Semantic Segmentation(ICCV2015)

    论文源址:https://arxiv.org/abs/1505.04366 tensorflow代码:https://github.com/fabianbormann/Tensorflow-Decon ...

  10. 常见的爬虫分析库(4)-爬虫之PyQuery

    PyQuery 是 Python 仿照 jQuery 的严格实现.语法与 jQuery 几乎完全相同. 官方文档:http://pyquery.readthedocs.io/ 安装 1 pip ins ...