浅谈杨辉三角【复习】
浅谈杨辉三角【复习】
杨辉三角,是二项式系数在三角形中的一种几何排列。
顾定义思用途:二项式定理和排列数预处理
重点在于它的性质(说不定就无意间考了):
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
一:第n行的元素个数有n个;!
二:第n行的所有元素之和为2n-1;!!!!
三: 第n行第m个数的值为C(n-1, m-1),其中C为组合数;!!
四:(a+b)n 展开后的各项系数等于第n+1行的值;!!
五:第n行第m个数的奇偶判断,及C(n-1,m-1)的奇偶判断:(m-1)&(n-1)==(m-1)? 奇 : 偶;!!!!!!
例题一:
http://acm.hdu.edu.cn/showproblem.php?pid=6143
题目大意:
一个人的名字有名和姓,名和姓上各有n个字符位置,每个位置的字符从m个字符里面选择。问你有多少个人的名字其名和姓上没有相同的字符。(名或姓内部可以重复)
分析:
考虑第一组盒子,假设用了i种颜色的球,
那么设f(i)为用i种颜色的球(每种颜色必须用到)填n个盒子的种数,显然f(1)=1
则f(i)=in-c(1,i)×f(1)-c(2,i)×f(2)-....-c(i-1,i)×f(i-1)
code:
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define mods 1000000007
int n,m;
long long _power(long long a ,long long b) //快速幂
{
long long res=1;
while(b)
{
if(b & 1)
res =res*a%mods;
a =a*a%mods;
b>>=1;
}
return res;
}
long long C[2005][2005];
long long f[2005]; //用用i种颜色的球(每种颜色必须用到)填n个盒子的种数
void calculateC()
{
for(int i=1;i<=2005;i++)
{
C[0][i]=C[i][i]=1;
for(int j=1;j<i;j++)
{
C[j][i]=(C[j-1][i-1]+C[j][i-1])%mods; //用动态规划求出组合数的转移方程
}
}
}
void solve()
{
f[1]=1;
for(int i=2;i<=n;i++)
{
long long temp=0;
for(int j=1;j<i;j++)
{
temp=(temp+(C[j][i]*f[j])%mods)%mods;
}
f[i]=(_power(i,n)-temp+mods)%mods;
}
int cnt;
long long ans=0;
int k=m<=n?m-1:n;
for(int i=1;i<=k;i++)
{
cnt=(((C[i][m]*f[i])%mods)*_power(m-i,n))%mods;
ans+=cnt;
ans%=mods;
}
cout<<ans<<endl;
}
int main()
{
int t;
cin>>t;
calculateC();
while(t--)
{
cin>>n>>m;
solve();
}
return 0;
}
后续:这个题不简单
例题二
http://acm.hdu.edu.cn/showproblem.php?pid=6129
题目大意:给你一个数列a[1], a[2], a[3], a[4], ... , a[n],操作一次后变为a[1], a[1] ^ a[2], a[1] ^ a[2] ^ a[3], ..., a[1] ^ a[2] ^ a[3] ...a[n],让你计算出m次操作后的数列(m<=1e9)
分析:
先不管那么多,看到1e9,打表找规律
code:
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <cstring>
#include <queue>
#include <set>
#include <string>
#include <map>
#include <climits>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 2e5 + 5;
const int mod = 1e9 + 7;
const int INF = 1e8 + 5;
const ll inf = 1e15 + 5;
const db eps = 1e-6;
int a[maxn], b[maxn];
void solve() {
int n, m; scanf("%d%d", &n, &m);
memset(b, 0, sizeof(b));
memset(a, 0, sizeof(a));
for (int i=1; i<=n; i++) scanf("%d", &a[i]);
for (int i=1; i<=n; i++) {
int x=i+m-2, y=i-1;
if ((x&y)==y) {
for (int j=i; j<=n; j++)
b[j]^=a[j-i+1];
}
}
for (int i=1; i<=n; i++) {
if (i-1) printf(" ");
printf("%d", b[i]);
}
puts("");
}
int main() {
int t = 1, cas = 1;
scanf("%d", &t);
while(t--) {
solve();
}
return 0;
}