【题解】洛谷P2822 [NOIP2016TG ]组合数问题 (二维前缀和+组合数)
2024-09-01 17:00:06
洛谷P2822:https://www.luogu.org/problemnew/show/P2822
思路
由于n和m都多达2000
所以暴力肯定是会WA的
因为整个组合数是不会变的
所以我们想到存下这个组合数(杨辉三角)阵型
注意要用二维前缀和存下 后来的k次询问就可以用O(1)解答
关于二维前缀和
用此图可以解答:
关键代码:s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1];
来自dalao的口诀:上加左 减左上 加自己
代码
#include<iostream>
using namespace std;
#define maxn 2005
int c[maxn][maxn],s[maxn][maxn];
int t,k,m,n;
void build()
{
for(int i=;i<=;i++)
{
c[i][]=c[i][i]=;
for(int j=;j<=i-;j++)
c[i][j]=(c[i-][j-]+c[i-][j])%k;//杨辉三角递推
}
for(int i=;i<=;i++)
{
for(int j=;j<=i;j++)
{
s[i][j]=s[i][j-]+s[i-][j]-s[i-][j-];
if(!c[i][j])//如果c[i][j]为0说明 它是k的倍数
s[i][j]+=;//ans加1
}
s[i][i+]=s[i][i];//详见后文注释<1>
}
}
int main()
{
cin>>t>>k;
build();
while(t)
{
t--;
cin>>n>>m;
if(m>n) m=n;//m不能大于n
cout<<s[n][m]<<endl;
}
}
注释<1>:
补齐杨辉三角的右上角一排 否则二维前缀和在最右边无法算出
对于k=2
例: 1 0 0 如果不加这句代码 0
1 1 0 0 0 0 0
1 2 1 0 1 1 1 0 1 0
1 3 3 1 0 1 1 1 1 0 1 0 0
对于最右边的一排1的位置的前缀和无法计算 因为没有上面的值
最新文章
- linux下进程权限分析
- 解决MyEclipse报错问题
- 6*17点阵的Window程序, Java写的。
- 【转】C 宏
- openstack命令
- G-sensor驱动分析
- SQL Select的执行顺序
- 被忽视的META标签之特效
- MFC之窗体改动工具栏编程状态栏编程程序启动画面
- 在CDockablePane中嵌入对话框
- 无限“递归”的python程序
- C++将一个数组内容赋给另一个数组
- 【原】js数组对象去重最简单的方法
- C# 以管理员权限删除文件
- [android] 分析setting源代码获取SD卡大小
- 单片机pwm控制基本原理详解
- SSH原理和应用
- vue2.0 之事件处理器
- linux shell学习一
- 手动编写一个简单的loadrunner脚本
热门文章
- unity向量计算
- php服务端学习感想
- 服务器LIUNX之如何解决矿机问题
- socket programming
- 关于datagridview中checkbox列在选中行的情况下无法操作值
- Jmeter使用CSV Data Set Config参数化数据不重复的多次循环执行(实现多用户多次抽奖功能)
- 在crontab中执行脚本重要事项
- Oracle:environment variable ";PATH"; does not exceed the recommended length
- 架构蓝图--软件架构 ";4+1"; 视图模型
- tdf sample