Yali7月集训Contest2 T1 Cube 题解
Posted rye-catcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Yali7月集训Contest2 T1 Cube 题解相关的知识,希望对你有一定的参考价值。
题目链接:
连我们都只有纸质题目...话说雅礼集训都是这样的吗...
大意
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 ",solve(m,n)); } return 0; }
以上是关于Yali7月集训Contest2 T1 Cube 题解的主要内容,如果未能解决你的问题,请参考以下文章