P5239 回忆京都题解
传送门
前排声明:题解写的比较累赘...把一些基本的恒等式都讲了一遍...(部分证明借鉴了《具体数学》一书)
如果您已经掌握了这些基础的话建议还是去看其他dalao们的题解吧qwq...
1.基本恒等式
我们把(dbinom{n}{k})符号读作"n选取k"
即从n个元素的集合中选取k个元素作为子集的方案总数
对于该集合的第一个元素的可能,有n种选择
对第二个元素,有n-1种选择,3,4,5.....也同理
同时,对于每k个元素组成的子集都恰好有(k!)种不同的排序
根据乘法原理
得到公式
(dbinom{n}{k}={dfrac{n*(n-1)...*(n-k+1)}{k!}})
(基本恒等式)
2.对称恒等式
先来看个图
观察一下不难发现规律
(dbinom{n}{k}=dbinom{n}{n-k})
(对称恒等式)
至于正确性也显而易见
从n个物品中选k个物品就相当于指定的n-k种物品不被选取
3.吸收恒等式
我们知道,二项式系数的基本恒等式为
(dbinom{n}{k}={dfrac{n*(n-1)...*(n-k+1)}{k!}})
可以将式子转化为
(dbinom{n}{k}={dfrac{n}{k}*dfrac{(n-1)...*(n-k+1)}{(k-1)!}})
得到式子(dbinom{n}{k}=dfrac{n}{k}dbinom{n-1}{k-1})
两边同乘k,得(kdbinom{n}{k}=ndbinom{n-1}{k-1})恒等式1
根据这个式子,再利用之前的恒等式1
还可以得到式子
((n-k)dbinom{n}{k}=(n-k)dbinom{n}{n-k})(根据对称性)
(=ndbinom{n-1}{n-1-k})(根据恒等式1)
(=ndbinom{n-1}{k})---(根据对称性)恒等式2
4.加法公式
观察一下前面的那张表,不难发现一个规律:
(dbinom{n}{k}=dbinom{n-1}{k-1}+dbinom{n-1}{k})
推导的话也很简单
根据之前吸收恒等式里的恒等式1和恒等式2
得出
(dbinom{n}{k}=(n-k)dbinom{n}{k}+kdbinom{n}{k}=ndbinom{n-1}{k}+ndbinom{n-1}{k-1})
5.题目
大致题意:
q次询问,每次都给一个m跟n,求
(sumlimits_{i=1}^nsumlimits_{j=1}^mC^i_j)
根据前面的加法公式,很容易可以解出这题
一共有n次询问,如果一次一次的去加的话肯定会超时
可以考虑使用二维前缀和来优化
至于二维前缀和怎么用,前面的dalao们已经写的很清楚了,为了让题解看起来不是那么的水,彩笔这里就再粗糙的写一遍吧
从图中不难看出,对于每一个sum[i][j],都有
sum[i][j]=sum[i][j-1]+sum[i-1][j]+a[i][j]-sum[i-1][j-1]
因为这里面有一个对(1926081719260817)取模操作
相减可能会产生负数
比如说我们取模后(sum[i][j-1]+sum[i-1][j]+a[i][j]=1)
而(sum[i-1][j-1]=1926081719260816)
很明显,相减为负
至于如何避免其实也很简单,只要再加上一个模数就可以了,相当于是加上之前那个被模掉的部分
贴上丑陋的代码:
#include<bits/stdc++.h>
using namespace std;
long long mo=19260817;
int n,a[1005][1005];
int sum[1005][1005];
int main(){
a[0][0]=1;
for(int i=1;i<=1002;i++){
for(int j=1;j<=1002;j++){
a[i][0]=a[i][i]=1;
a[i][j]=(a[i-1][j]+a[i-1][j-1])%mo;
}
}
for (int i=1;i<=1002;i++)
for (int j=1;j<=1002;j++){
sum[i][j]=(sum[i-1][j]+sum[i][j-1]+a[i][j]-sum[i-1][j-1]+mo)%mo;
}
cin>>n;
for(int i=1;i<=n;i++){
int l,r;
cin>>l>>r;
cout<<sum[r][l]<<endl;
}
return 0;
}
如有错误还请大佬们指出
话说没人会来看我这个菜比的题解吧qwq...