天天看點

P5239 回憶京都(洛谷3月月賽T2)solutioncode

題目描述

射命丸文在取材中發現了一個好玩的東西,叫做組合數。

組合數的定義如下:從n個不同元素中,任取m(m≤n)個元素并成一組,叫做從n個不同元素中取出m個元素的一個組合。所有組合的數量,就是組合數。

$\sum_{i=1}^n \sum_{j=1}^m C^i_j$,其中當i>j的時候,欽定$C^i_j$​為0

她也很快就算出來了,不過對自己的答案不是很充滿信心,是以你決定幫助她。然而沒事找事的她一下子算了q次對于不同的n,m的結果,是以這隻能勞煩你了。由于你不打算真正地幫助她,你無需把答案對998244353取模,也無需對64123取模,隻要告訴她對19260817取模之後的答案即可。

輸入輸出格式

輸入格式:

第一行輸入一個q,表示有q次詢問。

第二行開始,一共q行,每行兩個數字n,m,意思如題所示。

輸出格式:

一共q行,對于每一個詢問,都輸出一個答案。

資料範圍:n,m<=1000

solution

 容易想到預處理出楊輝三角, c[i][j]表示$c^j_i$ %mod,遞推公式是c[i][j]=c[i-1][j]+c[i-1][j-1],注意處理c[i][0]=1;

這樣每次詢問是O(nm),總的時間複雜度是O(qnm),TLE3個點,需要優化

通過模拟發現,題目中要求的數的和實際上在楊輝三角中是一個矩形的區域,也就是右下角下标為c[m][n]

例如,當m=4,n=3時,就是矩形區域的和,是以隻需要維護一個二維字首和就行了

P5239 回憶京都(洛谷3月月賽T2)solutioncode

一個大坑:當預處理二維字首和時因為經過了取模,是以容易出現新的字首和為負數的情況,而我們希望得到的一定是個正數,是以每一項s[i][j]=(s[i][j]+mod)%mod;

因為這個坑WA了三個

code

#include<cstdio>
#include<iostream>
#include<cstring>
#define mod 19260817//咳咳 
#define maxn 1020
using namespace std;
long long s[maxn][maxn],ts[maxn][maxn];
int n,m,t,x,ans,tmp;
void init(int n)
{
    for(int i=0;i<=n;++i)
    {
        s[i][0]=1;
    }
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=n;++j)
        {
            if(j<=i) s[i][j]=(s[i-1][j]+s[i-1][j-1])%mod;//楊輝三角 
            
            ts[i][j]=(ts[i-1][j]+ts[i][j-1]-ts[i-1][j-1]+s[i][j]+mod/*關鍵*/)%mod;//二維字首和 
        }
        
    }
          
         
}
int main()
{
    scanf("%d",&t);
    init(1010);//預處理楊輝三角與字首和 
    for(int k=1;k<=t;++k)
    {
        scanf("%d%d",&n,&m);
        printf("%lld\n",ts[m][n]);
    }
    return 0;
}      

轉載于:https://www.cnblogs.com/Liuz8848/p/10465826.html