• P5239 题解


    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...

  • 相关阅读:
    SPOJ LCS2
    SPOJ NSUBSTR
    1977: [BeiJing2010组队]次小生成树 Tree
    2002: [Hnoi2010]Bounce 弹飞绵羊
    P3690 【模板】Link Cut Tree (动态树)
    P2093 [国家集训队]JZPFAR
    2648: SJY摆棋子
    HDU 2966 In case of failure
    bzoj 一些题目汇总
    BZOJ3653谈笑风生——可持久化线段树+dfs序
  • 原文地址:https://www.cnblogs.com/xcxc82/p/13339567.html
Copyright © 2020-2023  润新知