Codeforces Round #295 (Div. 1) C. Pluses everywhere
来源:互联网 发布:云计算的具体应用 编辑:程序博客网 时间:2024/06/08 04:12
Codeforces Round #295 (Div. 1) C. Pluses everywhere
题目大意:
你有一个长度为n的'0-9'串,你要在其中加入k个'+'号,每种方案就会形成一个算式,算式算出来的值记做这次方案的贡献。
问:所有方案的贡献,对1e9+7取模。
n,k<=1e5.
首先我和zzd先探讨了一会儿暴力一点的做法,唔,非常好弄的是k*n^2,枚举子串,考虑这个子串出现在了多少个方案中,然后就是枚举左边多少个'+',然后一堆组合数...啪啦啪啦...
然后觉得既然两边分的'+'号加起来的总和相等,是不是可以不用枚举呢,比如一个预处理什么的...啪啦啪啦...
好啦,感觉上面的研究不下去了...
然后又想,不是要O(n)么,感觉像是对每个字符考虑,考虑它作为个位、十位、百位...等等的贡献。
怎么算呢?似乎现在状态比刚才好一点了?...
首先是i作为这一段的开头,j作为这一段的结尾。
现在是i作为这一段的第j位...好啦...然后我还是想不到= =
ZZD就开始秒题啦...因为原题相当于在n-1的空隙中放k个隔板。
那么若i不在最后一段,那么我先强制在i+j后插一个隔板[保证i是第j位],并且强制i到i+j之间的j-1个位置不能放,同时i+j后的位置已经放了,所以还剩n-j-1个位置,k-1个隔板,即C(n-j-1,k-1)种方案。
若i在最后一段,那么我强制i到n的j-1个位置不能放,就是C(n-j,k)种方案。
好啊,发现这个东西居然和i都没有关系,那我是不是可以把i绑起来算呢?[当然i可以用来判断这个位置是不是在最后一段,也可以判断这里到底能不能作为第j位]。
于是我们可以枚举长度l。
所以在可行的位置[1...n-l+1]中,最后一位是作为最后一段,其它的值是相同的,所以就是一个前缀和*这一坨+最后一个位置的特判,就可以了。
[怎么线性求组合数?] <-大家都会吧?...
不过看在我不会的份上,还是说一下吧...就是利用的是逆元的思想,C(n,r)=n!/(n-r)!/r!,那么要是预处理出所有的阶乘以及所有阶乘的逆元,每次查询就是O(1)的了...
预处理阶乘O(n)没问题,预处理出阶乘的逆元怎么办呢?...
机智的ZZD发现:1/(n-1)!=1/n!*n
%%%,先算n!的逆元,然后倒过来再乘一遍就可以了。
[上面的描述可能和代码中的含义有小小的不同,代码中l表示的是长度len-1,所以和上面有小小不同]
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100010;const int mod=1e9+7;typedef long long ll;int n,k;ll s[maxn],lv[maxn],lv1[maxn];char num[maxn];ll ans;ll C(int n,int r){ if(r>n) return 0; if(r==0 || n==r) return 1; return ((lv[n]*lv1[r])%mod*lv1[n-r])%mod;}ll power(ll a,int k){ ll ans=1; while(k){ if(k&1) ans=ans*a%mod; k>>=1;a=a*a%mod;} return ans;}int main(){#ifndef ONLINE_JUDGE freopen("C.in","r",stdin); freopen("C.out","w",stdout);#endif scanf("%d%d",&n,&k); scanf("%s",num+1); for(int i=1;i<=n;i++) s[i]=(s[i-1]+num[i]-'0')%mod; lv[0]=1; for(int i=1;i<=n;i++) lv[i]=lv[i-1]*i%mod; lv1[n]=power(lv[n],mod-2); for(int i=n-1;i>=1;i--) lv1[i]=lv1[i+1]*(i+1)%mod; for(int l=0;l<n;l++){ ans=(ans+(s[n-l-1]*C(n-l-2,k-1))%mod*power(10,l))%mod; ans=(ans+((num[n-l]-'0')*C(n-l-1,k))%mod*power(10,l))%mod; } printf("%I64d",ans); return 0;}
- 【组合数学】 Codeforces Round #295 (Div. 1) C - Pluses everywhere
- Codeforces Round #295 (Div. 1) C. Pluses everywhere
- 【Codeforces】 Codeforces Round #295 (Div. 1) Pluses everywhere
- Codeforces Round #295 (Div. 1) C. Pluses everywhere (组合数学+乘法逆元)
- Codeforces Round #295 (Div. 2) E. Pluses everywhere
- Codeforces 520E/521C Pluses everywhere
- #295 (div.2) E.Pluses everywhere
- codeforces 520E Pluses everywhere
- CodeForces 520E Pluses everywhere
- Codeforces Round #364 div.2 C. They Are Everywhere 【尺追法】
- Codeforces Round #364 (Div. 2) C. They Are Everywhere(二分)
- Codeforces Round #364 (Div. 2)C. They Are Everywhere
- Codeforces Round #364 (Div. 2) C. They Are Everywhere
- Codeforces 520E. Pluses everywhere 数学
- codeforces 520E Pluses everywhere (数学)
- codeforces 520E Pluses everywhere (数学题)
- Codeforces Round #364 (Div. 2) C. They Are Everywhere (尺取法)
- Codeforces Round #364 (Div. 2) C They Are Everywhere(滑窗)
- csapp 2.11
- L2L vpn原理及配置方法
- 文章标题
- 关于spring boot 中App类位置不同导致出错的问题的解决方法
- 安卓android的sdk安装路径和方法
- Codeforces Round #295 (Div. 1) C. Pluses everywhere
- 社区新版首页上线,开启找bug模式
- hdu3294-Girls' research
- 我在React Native开发中遇到的一些坑
- 洛谷 P1438 无聊的数列
- GitBash+GitLab+Eclipse使用攻略非常详细版
- HDU-1846-Brave Game
- 嵌入式Linux中的wpa_supplicant等工具移植
- 高并发和大数据的解决方式