1. 题目描述
有两种不同类型的循环,并给出一个由1、2组成的序列,表示嵌套的循环类型。
问这样组着的循环一共需要多少次循环?并将结果模364875103。
2.基本思路
显然,每当遇到一个类型1的序列,即可以判定12...2的嵌套循环共多少次,而1类型的循环次数为常亮。
因此,将原序列从1分开,并将每个子序列的循环次数相乘即为总的循环次数。
1 共循环n次 = C[n][1]
12 共循环n*(n+1)/2次 = C[n+1][2]
122 共循环n*(n+1)*(n+2)/6次 = C[n+2][3]
12..2 |2|=m 共循环n*(n+1)*(n+2)/6次 = C[n+m-1][m]
由Lucas定理可知,假设p为素数,有
比较悲剧的是364875103是个合数,将它拆解为两个素数并使用LUCAS后,
我们可以知道ans=a1(mod p1), ans=a2(mod p2), 且p1, p2互素,求ans = ? (mod p1*p2)。
使用中国剩余定理。
使用欧拉定理求逆。
3. 代码
1 /* 4373 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 #define LL __int64 43 44 const int maxn = 25; 45 const int mod1 = 97; 46 const int mod2 = 3761599; 47 const int mod = 364875103; 48 LL fact1[mod1+15]; 49 LL fact2[mod2+15]; 50 LL e1, e2; 51 int pos[maxn]; 52 int n, m, k; 53 54 LL Pow(LL base, LL n, LL mod) { 55 LL ret = 1; 56 57 base %= mod; 58 while (n) { 59 if (n & 1) 60 ret = ret * base % mod; 61 base = base * base % mod; 62 n >>= 1; 63 } 64 65 return ret; 66 } 67 68 void init() { 69 fact1[0] = fact2[0] = 1; 70 rep(i, 1, mod1) 71 fact1[i] = fact1[i-1] * i % mod1; 72 rep(i, 1, mod2) 73 fact2[i] = fact2[i-1] * i % mod2; 74 e1 = mod2 * Pow(mod2, mod1-2, mod1); 75 e2 = mod1 * Pow(mod1, mod2-2, mod2); 76 77 #ifndef ONLINE_JUDGE 78 printf("e1 = %I64d, e2 = %I64d\n", e1, e2); 79 #endif 80 } 81 82 LL C(LL n, LL m, LL mod, LL *fact) { 83 if (n < m) return 0; 84 return fact[n] * Pow(fact[m]*fact[n-m], mod-2, mod) % mod; 85 } 86 87 LL Lucas(LL n, LL m, LL mod, LL *fact) { 88 if (m == 0) return 1; 89 return C(n%mod, m%mod, mod, fact) * Lucas(n/mod, m/mod, mod, fact); 90 } 91 92 void solve() { 93 LL ans = 1, tmp; 94 LL a1, a2; 95 96 rep(i, 0, k) { 97 m = pos[i+1]-pos[i]; 98 a1 = Lucas(n+m-1, m, mod1, fact1); 99 a2 = Lucas(n+m-1, m, mod2, fact2); 100 tmp = (a1*e1 + a2*e2) % mod; 101 #ifndef ONLINE_JUDGE 102 printf("a1 = %I64d, a2=%I64d, tmp=%I64d\n", a1, a2, tmp); 103 #endif 104 ans = ans * tmp % mod; 105 } 106 107 printf("%I64d\n", ans); 108 } 109 110 int main() { 111 ios::sync_with_stdio(false); 112 #ifndef ONLINE_JUDGE 113 freopen("data.in", "r", stdin); 114 freopen("data.out", "w", stdout); 115 #endif 116 117 int t; 118 119 init(); 120 scanf("%d", &t); 121 rep(tt, 1, t+1) { 122 scanf("%d%d%d", &n, &m, &k); 123 rep(i, 0, k) 124 scanf("%d", &pos[i]); 125 pos[k] = m; 126 printf("Case #%d: ", tt); 127 solve(); 128 } 129 130 #ifndef ONLINE_JUDGE 131 printf("time = %d.\n", (int)clock()); 132 #endif 133 134 return 0; 135 }
4. 数据生成器
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 20 10 bound = 10**5 11 fout.write("%d\n" % (t)) 12 for tt in xrange(t): 13 n = randint(20, bound) 14 m = randint(20, bound) 15 k = randint(1, 15) 16 fout.write("%d %d\n%d " % (n, m, k)) 17 L = [0] 18 st = set() 19 for i in xrange(1, k): 20 while True: 21 x = randint(1, m) 22 if x not in st: 23 break 24 L.append(x) 25 st.add(x) 26 L = sorted(L) 27 fout.write(" ".join(map(str, L)) + "\n") 28 29 30 def MovDataIn(): 31 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 32 shutil.copyfile("data.in", desFileName) 33 34 35 if __name__ == "__main__": 36 GenDataIn() 37 MovDataIn()