1. 程式人生 > >Yali7月集訓Contest2 T1 Cube 題解

Yali7月集訓Contest2 T1 Cube 題解

是我 define 基礎 for 數字 test printf 發現 st2

  • 題目鏈接:

    連我們都只有紙質題目...話說雅禮集訓都是這樣的嗎...

  • 大意

    0維基本圖形是一個點

    1維基本圖形是一條線段

    2維基本圖形是一個正方形

    3維基本圖形是一個正方體

    4維基本圖形是...

    \(n\)維基礎圖形中有多少個\(m\)維基礎圖形\((n>=m)\)並對\(998244353\)取模

  • 分析

    手玩樣例打表吼啊

    當然還是要暗中觀察一下啦

    線段變成正方形,點數變為原來兩邊,邊數除了變為原來兩倍之外還要加上原來點數所對應連起來的邊

    正方形變正方體也類似

    於是我就yy出一個遞推式\(num[x][m]=num[x-1][m]*2+num[x-1][m-1]\)

    \(num[x][m]\)

    表示\(x\)維基礎圖形中含有\(m\)維基礎圖形的數量

    然後我們可以打一張表

    然後就有dalao發現了規律(我比較傻考場上都手玩出每一項能整除2的冪都沒發現規律)

    \(num[n][m]/2^{n-m}=C^n_m\)

    然後就ok了

  • 註意

    在訂正這道題時發現幾個值得註意的地方

    • 線性求逆元時我原來的方法不行

      原來我這麽線性求逆元

      inv[i]=(-(p/i)*inv[p%i]%p);

      結果我發現數字一大就GG了

      這是大佬的線性求逆元

      inv[i]=(ll)(p-(p/i))*inv[p%i]%p;

      這就很穩了

    • 一個有趣的性質

      逆元的階乘是原來數字階乘的逆元

      很有趣,好象可證

  • 代碼:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cstring>
    #include <cctype>
    #include <map>
    #define ri register int 
    #define ll long long 
    using namespace std;
    const int maxn=100005;
    const int inf=0x7fffffff;
    const int p=998244353;
    template <class T>inline void read(T &x){
     x=0;int ne=0;char c;
     while(!isdigit(c=getchar()))ne=c==‘-‘;
     x=c-48;
     while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
     x=ne?-x:x;
     return ;
    }
    int inv[maxn],twopow[maxn],fac[maxn];
    inline void pre(){
     inv[0]=inv[1]=1,fac[1]=1,twopow[0]=1,twopow[1]=2;
     for(ri i=2;i<=100002;i++){
         fac[i]=(ll)fac[i-1]*i%p;
         inv[i]=(ll)(p-(p/i))*inv[p%i]%p;
         twopow[i]=(ll)(twopow[i-1]<<1)%p;
         //cout<<fac[i]<<‘ ‘<<inv[i]<<‘ ‘<<twopow[i]<<endl;
     }
     for(ri i=2;i<=100002;i++){
         inv[i]=(ll)inv[i]*inv[i-1]%p;//比較神奇,逆元的階乘是原來數的階乘的逆元
     }
     return ;
    }
    int t;
    inline int solve(int m,int n){
     if(m==0)return twopow[n];
     if(n==m)return 1;
     return (ll)fac[n]*inv[n-m]%p*twopow[n-m]%p*inv[m]%p;
    }
    int main(){
     int n,m;
     read(t);
     pre();
     while(t--){
         read(n),read(m);
         printf("%d\n",solve(m,n));
     }
     return 0;
    }

Yali7月集訓Contest2 T1 Cube 題解