P4345 [SHOI2015]超能粒子炮·改 lucas
阿新 • • 發佈:2019-03-28
-i 整數 cti kkk 余數 include () src tdi
我來解釋一下後一步咋來的,就是把Ci/p提出去,然後類似整數分塊,每次往下分都會算一部分,預處理楊輝三角前綴和,我看的洛谷第二個題解。
題幹:
題目描述 曾經發明了腦洞治療儀與超能粒子炮的發明家 SHTSC 又公開了他的新發明:超能粒子炮?改——一種可以發射威力更加強大的粒子流的神秘裝置。 超能粒子炮?改相比超能粒子炮,在威力上有了本質的提升。它有兩個參數nnn,kkk,它會向每個編號為000到kkk(包含兩端)的位置iii發射威力為Cnimod2333C_{n}^{i} mod 2333Cni?mod2333的粒子流。 現在 SHTSC 給出了他的超能粒子炮?改的參數,讓你求出其發射的粒子流的威力之和除以233323332333所得的余數。 輸入輸出格式 輸入格式: 第一行一個整數 ttt表示數據組數。 之後 ttt 行,每行兩個整數 nnn、kkk,含義如題面描述。 輸出格式: ttt 行,每行一個整數,表示其粒子流的威力之和模233323332333 的值。
代碼:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #defineclean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < ‘0‘ || c > ‘9‘) if(c == ‘-‘) op = 1; x = c - ‘0‘; while(c = getchar(), c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar(‘-‘), x = -x; if(x >= 10) write(x / 10); putchar(‘0‘ + x % 10); } const int N = 2450; const int mod = 2333; ll t,n,k,c[N][N],f[N][N]; ll lucas(ll n,ll m) { if(!m) return 1; if(n == m) return 1; if(n < m) return 0; return c[n % mod][m % mod] * lucas(n / mod,m / mod) % mod; } ll F(ll n,ll k) { if(k < 0) return 0; if(!n) return 1; if(!k) return 1; if(n < mod && k < mod) return f[n][k]; return (F(n / mod,k / mod - 1) * f[n % mod][mod - 1] % mod + lucas(n / mod,k / mod) * f[n % mod][k % mod]) % mod; } int main() { read(t); c[0][0] = 1; duke(i,1,2350) { c[i][0] = c[i][i] = 1; duke(j,1,i - 1) { c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod; } } f[0][0] = 1; duke(i,0,2350) { f[i][0] = 1; } duke(i,0,2350) { duke(j,1,2350) { f[i][j] = (f[i][j - 1] + c[i][j]) % mod; } } while(t--) { read(n);read(k); printf("%lld\n",F(n,k)); } return 0; }
P4345 [SHOI2015]超能粒子炮·改 lucas