Codeforces 520E. Pluses everywhere 数学

520E - Pluses everywhere/521C
- Pluses everywhere

Idea: Endagorion

Preparation: gchebanovDPR-pavlin

Consider some way of placing all the pluses, and a single digit di (digits
in the string are numbered starting from 0 from left to right). This digit gives input of di·10l to
the total sum, where l is the distance to the nearest plus from the right, or to the end of string if there are no pluses there. If we sum up these quantities
for all digits and all ways of placing the pluses, we will obtain the answer.

For a given digit di and
some fixed l, how many ways are there to place the pluses? First of all, consider the case when the part containing the digit di is
not last, that is, i?+?l?<?n?-?1. There are n?-?1 gaps
to place pluses in total; the constraint about di and
the distance l means that after digits di, ..., di?+?l?-?1 there
are no pluses, while after the digit di?+?l there
should be a plus. That is, the string should look as follows:

Here a dot means a gap without a plus, and a question mark means that it‘s not important whether there is a plus or not. So, out of n?-?1possible gaps
there are l?+?1 gaps which states are defined, and there is one plus used in these gaps. That means that the other (n?-?1)?-?(l?+?1)?=?n?-?l?-?2 gaps
may contain k?-?1 pluses in any possible way; that is, the number of such placements is .
A similar reasoning implies that if the digit di is
in the last part, that is, i?+?l?=?n?-?1, the number of placements is .

To sum up, the total answer is equal to

Let us transform the sum:

To compute these sums, we will need to know all powers of 10 up to n-th (modulo 109?+?7),
along with the binomial coefficients. To compute the binomials, recall that ,
so it is enough to know all the numbers k! for k upto n,
along with their modular inverses. Also we should use the prefix sums of di,
that is, the array .
The rest is simple evaluation of the above sums.

The total complexity is ,
because the common algorithms for modular inverses (that is, Ferma‘s little theorem exponentiation or solving a diophantine equation using the Euclid‘s algorithm) have theoritcal worst-case complexity of .
However, one can utilize a neat trick for finding modular inverses for first n consecutive numbers in linear time for a total complexity of O(n);
for the description of the method refer to this comment by Kaban-5 (not
sure why it has a negative rating, I found this quite insightful; maybe anyone can give a proper source for this method?).

Challenge: now we want to find the sum of all expressions that are made by placing k pluses with a?≤?k?≤?b;
that is, we want to find the sum of the answers for the original problem with k?=?a,?...,?b; here a and b can
be any integers with 0?≤?a?≤?b?≤?n?-?1. There is an obviousO(n2) solution:
just find the answers for all k separately. Can you find a linear solution?

E. Pluses everywhere

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Vasya is sitting on an extremely boring math class. To have fun, he took a piece of paper and wrote out n numbers on a single line. After that, Vasya began
to write out different ways to put pluses ("+") in the line between certain digits in the line so that the result was a correct arithmetic expression;
formally, no two pluses in such a partition can stand together (between any two adjacent pluses there must be at least one digit), and no plus can stand at the beginning or the end of a line. For example, in the string 100500,
ways 100500 (add no pluses), 1+00+500 or 10050+0 are
correct, and ways 100++500, +1+0+0+5+0+0 or 100500+ are
incorrect.

The lesson was long, and Vasya has written all the correct ways to place exactly k pluses in a string of digits. At this point, he got caught having fun
by a teacher and he was given the task to calculate the sum of all the resulting arithmetic expressions by the end of the lesson (when calculating the value of an expression the leading zeros should be ignored). As the answer can be large, Vasya is allowed
to get only its remainder modulo 109?+?7.
Help him!

Input

The first line contains two integers, n and k (0?≤?k?<?n?≤?105).

The second line contains a string consisting of n digits.

Output

Print the answer to the problem modulo 109?+?7.

Sample test(s)

input

3 1
108

output

27

input

3 2
108

output

9

Note

In the first sample the result equals (1?+?08)?+?(10?+?8)?=?27.

In the second sample the result equals 1?+?0?+?8?=?9.

/* ***********************************************
Author        :CKboss
Created Time  :2015年03月04日 星期三 19时46分18秒
File Name     :E.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

typedef long long int LL;

const LL mod = 1e9+7LL;
const int maxn=100100;

int n,k;
LL a[maxn];
char str[maxn];

LL inv[maxn],presum[maxn];
LL jc[maxn],jcv[maxn],e[maxn];

void init()
{
	/// inv jc e
	inv[1]=1; jc[0]=1; jcv[0]=1;
	jc[1]=1; jcv[1]=1; e[0]=1; e[1]=10;
	for(int i=2;i<maxn;i++)
	{
		inv[i]=inv[mod%i]*(mod-mod/i)%mod;
		jc[i]=(jc[i-1]*i)%mod;
		jcv[i]=(jcv[i-1]*inv[i])%mod;
		e[i]=(e[i-1]*10LL)%mod;
	}
}

LL COMB(LL n,LL m)
{
	if(m<0||m>n) return 0LL;
	if(m==0||m==n) return 1LL;
	/// n!/((n-m)!*m!)
	LL ret=((jc[n]*jcv[n-m])%mod*jcv[m])%mod;
	return ret;
}

void solve(int n,int k)
{
	LL ans=0;
	if(k==0)
	{
		for(int i=n-1;i>=0;i--)
			ans=(ans+(e[n-1-i]*a[i])%mod)%mod;
		cout<<ans%mod<<endl;
		return ;
	}
	for(int l=0;l<=n-2;l++)
		ans=(ans+(e[l]*COMB(n-l-2,k-1)%mod*presum[n-l-2])%mod)%mod;
	for(int i=0;i<=n-1;i++)
		ans=(ans+((a[i]*e[n-1-i])%mod*COMB(i,k))%mod)%mod;
	cout<<ans%mod<<endl;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

	init();
	scanf("%d%d",&n,&k);
	scanf("%s",str);
	for(int i=0;i<n;i++)
	{
		a[i]=str[i]-'0';
		if(i==0) presum[i]=a[i];
		else presum[i]=(presum[i-1]+a[i])%mod;
	}
	solve(n,k);
    return 0;
}
时间: 2024-10-13 12:46:09

Codeforces 520E. Pluses everywhere 数学的相关文章

CodeForces 534C Polycarpus&#39; Dice (数学)

题意:第一行给两个数,n 和 A,n 表示有n 个骰子,A表示 n 个骰子掷出的数的和.第二行给出n个数,表示第n个骰子所能掷出的最大的数,这些骰子都有问题, 可能或多或少的掷不出几个数,输出n个骰子掷不出的数的个数. 析:我们只要考虑两个极端就好,考由其他骰子投出的最大值和最小值,还有自身在最大值和最小值,作一个数学运算就OK了.公式如下: 骰子的最大值-能投的最大值+能投的最小值-1. 代码如下: #include <cstdio> #include <string> #inc

【CodeForces 520E】Pluses everywhere

题意 n个数里插入k个+号,所有式子的和是多少(取模1000000007) (0 ≤ k < n ≤ 105). 分析 1.求答案,考虑每个数作为i位数(可为答案贡献10的i-1次方,个位i=1,十位i=2,...,最多n-k位): 那么它及后面 共i个数 之间不能有加号. 且只有前n-i+1个数可以作为i位,如果是an-i+1作为i位,那么后面都不能有加号,k个加号在a1到an-i+1之间,所以有C(n-i,k)次贡献(这么说怪怪的→_←),就是几种情况. a1 a2 a3 ... an-i+

Codeforces 468C Hack it!(数学)

题目链接:Codeforces 468C Hack it! 题目大意:给据题目定义,找到l,r,使得solve(l,r) % a = 0. 解题思路:f(x + 1e18) = f(x) + 1,所以有solve(x + 1, x+1e18) = solve(x, x+1e18-1) + 1,假定x为0,我们求出solve(0, 1e18) % a = k,那么a - k,即为区间需要移动的步长.solve(1e18) % a = 4518 1e17 % a #include <cstdio>

Codeforces 688D Remainders Game 数学

题意:Pari选了两个数x,k,已知k和n个数c[i],也能"知道"x%c[i],问是否x%k的值是否唯一?n,k,c[i]<=1e6 假如存在x1,x2满足:x1和x2同余c[i](i=1..n),但是x1%k!=x2%k 则此时不能确定x%k的值,答案为no即(x1-x2)%c[i]==0 因为lcm(c[1]..c[n])|(x1-x2) k不整除(x1-x2) k也不整除lcm(c[1]..c[n]) 该条件为必要条件.证明充分性很简单 构造x1=2*lcm,x2=lcm

Codeforces 17A Noldbach problem(数学)

题意 求n以内等于两个连续素数的和加上1的数的个数 n不大于1000 #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int N = 1000; int n, k, ans; bool isPrime (int a) { for (int i = 2; i <= sqrt (a); ++i) if (a % i == 0) return 0; retur

codeforces 688D - Remainders Game 数学相关

题意:给你x%ci=bi(x未知),是否能确定x%k的值(k已知) 分析:只要保证k能整除ci的最小公倍数即可,由于太大,所以通过暴力分解因子的办法来判断 #include <cstdio> #include <iostream> #include <ctime> #include <vector> #include <cmath> #include <map> #include <set> #include <st

Codeforces 911D. Inversion Counting (数学、思维)

题目链接:Inversion Counting 题意: 定义数列{ai|i=1,2,...,n}的逆序对如下:对于所有的1≤j<i≤n,若ai<aj,则<i,j>为一个逆序对.于是,对于一个数列a[1..n],给定m次操作.对于每一次操作,给定l,r(1≤l<r≤n),将序列a[l..r]倒置.求倒置后的逆序对的数量的奇偶性. 题解: 假设现在我们有一个序列并翻转这个序列[l,r]区间里面的数.假设某个数的k值是指在这个值后面小于这个数的数的个数,其实我们可以发现对于[1,l

Codeforces 932E Team Work 数学

Team Work 发现网上没有我这种写法.. i ^ k我们可以理解为对于每个子集我们k个for套在一起数有多少个. 那么我们问题就变成了 任意可重复位置的k个物品属于多少个子集. 然后我们枚举k个物品所占位置的个数 i , 然后需要计算有多少种方案能把k个不同物品放入i个桶中. 这个东西可以用dp[ i ][ j ] 表示 i 个物品放入 j 个桶中的方案数. dp[ i ][ j ] = dp[ i - 1 ][ j ] * j + dp[ i - 1 ][ j - 1 ] * j 然后就

Codeforces Beta Round #85 (Div. 1 Only) C (状态压缩或是数学?)

C. Petya and Spiders Little Petya loves training spiders. Petya has a board n × m in size. Each cell of the board initially has a spider sitting on it. After one second Petya chooses a certain action for each spider, and all of them humbly perform it