Shaass and Lights CodeForces - 294C
阿新 • • 發佈:2021-08-08
原題連結
考察:組合數學
思路:
我們不必模擬每次具體去掉什麼.因為去掉的蠟燭只能在熄滅的蠟燭左右倆側.對於區間\(2\),每次在左右端點選一個去掉,方法數是\(2^{8-4-1-1}\).但是區間1,3是特殊的,因為只有一種方法.
計算完區間內部的方法後,就是計算區間之間的方法數.這裡不能用插空法.是先有\(n-m\)個位置,將位置填滿的計算方法.
Code
#include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int N = 1010,M = 1000000007; int nums[N],n,m,C[N][N]; void init() { for(int i=0;i<N;i++) for(int j=0;j<=i;j++) if(!j) C[i][j] = 1; else C[i][j] = ((LL)C[i-1][j-1]+C[i-1][j])%M; } int qsm(int a,int k,int m) { if(k<0) return 1; int res = 1; while(k) { if(k&1) res = (LL)res*a%m; a = (LL)a*a%m; k>>=1; } return res; } int main() { scanf("%d%d",&n,&m); init(); int res = 1,now = n-m; if(n==m) {puts("1");return 0;} for(int i=1;i<=m;i++) scanf("%d",&nums[i]); sort(nums+1,nums+m+1); for(int i=2;i<=m;i++) { int len = nums[i]-nums[i-1]-1; res = (LL)res*qsm(2,len-1,M)%M; } nums[m+1] = n+1; for(int i=1;i<=m+1;i++) { res = (LL)res*C[now][nums[i]-nums[i-1]-1]%M; now-=nums[i]-nums[i-1]-1; } printf("%d\n",res); return 0; }