锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
澶ф剰錛氬N闃跺畬鍏ㄥ浘鐨勮竟鏌撹壊錛屾眰鍦ㄧ疆鎹㈢兢鐨勪綔鐢ㄤ笅錛屼笉絳変環(huán)鐨勬煋鑹叉柟娉曟暟錛屽叡鏈塵涓鑹詫紝 N <= 54錛?緇撴灉妯′笂璐ㄦ暟p
鎬濊礬錛氭瘡涓疆鎹㈠垎瑙d負(fù)鑻ュ共寰幆緇擄紝闀垮害涓篿鐨勫驚鐜粨鏈塶i涓?鍒檚igma{i * ni} = N. 姣忎竴涓疆鎹㈠敮涓瀵瑰簲涓涓猲鍏冪粍(n1, n2, ... , nN), 姣忎釜n鍏冪粍鍙敱N!/pi{i^ni}/pi{ni!}涓疆鎹㈠緱鍒幫紝 (pi{}, sigma{}, 鍒嗗埆琛ㄧず姹傜Н鍜屾眰鍜?銆傚垎鍒綆楀驚鐜粨鍐呴儴瀛愬畬鍏ㄥ浘涓瓑浠瘋竟綾葷殑涓暟([L/2])錛屽拰寰幆緇撲箣闂寸殑絳変環(huán)杈圭被鐨勪釜鏁?gcd(L1, L2)), 姹傚嚭鎬葷瓑浠瘋竟綾諱釜鏁皊um錛屽緱鍑烘瘡涓猲鍏冪粍涓嬪搴旂殑鏌撹壊m^sum銆傛灇涓炬墍鏈塶鍏冪粍銆?br> 緇嗚妭錛氭灇涓炬墍鏈塶鍏冪粍鐨勪唬浠峰緢楂橈紝闇瑕佸涓浜涢噺棰勫鐞嗭紝浣滃父鏁頒紭鍖栥?br>
2
3 using namespace std;
4 typedef long long int64;
5 const int maxn = 64;
6 int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }
7 int n, m, p, x[maxn], d[maxn][maxn], cn2[maxn];//x涓簄鍏冪粍錛宒[i][j] = gcd(i, j), cn2[i] = i * (i - 1) / 2
8 int64 rv[maxn], fac[maxn], facv[maxn];//rv[i] = inv(i, p), fac[i] = i!, facv = inv(i!, p)
9 int64 ans = 0;
10 int64 pw(int64 a, int64 b, int64 M) {
11 if(b == 0) return 1;
12 int64 tmp = pw(a, b >> 1, M);
13 tmp = tmp * tmp % M;
14 if(b & 1) return (tmp * a) % M;
15 return tmp;
16 }
17 int64 inv(int64 a, int64 b) { return pw(a, b - 2, b); }//a妯¤川鏁癰鐨勯嗗厓
18 void init() {
19 rv[1] = fac[0] = 1;
20 for(int i = 2; i <= n; ++ i) rv[i] = inv(i, p);
21 for(int i = 1; i <= n; ++ i) fac[i] = i * fac[i - 1] % p;
22 for(int i = 0; i <= n; ++ i) facv[i] = inv(fac[i], p);
23 }
24 int64 cal() {
25 int64 sum = 0, toadd = 1;
26 for(int i = 1; i <= n; ++ i) sum += i / 2 * x[i] + cn2[x[i]] * i;
27 for(int i = 1; i <= n; ++ i) for(int j = i + 1; j <= n; ++ j) if(x[i] && x[j])
28 sum += x[i] * x[j] * d[i][j];
29 for(int i = 1; i <= n; ++ i) {
30 int64 tmp = rv[i];
31 for(int j = 0; j < x[i]; ++ j)
32 toadd = toadd * tmp % p;
33 toadd = toadd * facv[x[i]] % p;
34 }
35 toadd = toadd * pw(m, sum, p) % p;
36 return toadd;
37 }
38 void dfs(int t, int sum) {//鏋氫婦鎵鏈塶鍏冪粍
39 if(sum == n) {
40 ans = (ans + cal()) % p;
41 return;
42 }
43 if(t > n) return;
44 for(int i = 0; i * t + sum <= n; ++ i) {
45 x[t] = i;
46 dfs(t + 1, t * i + sum);
47 }
48 }
49 int main()
50 {
51 // freopen("in", "r", stdin);
52 for(int i = 1; i < maxn; ++ i)
53 for(int j = 1; j < maxn; ++ j)
54 d[i][j] = gcd(i, j);
55 for(int i = 0; i < maxn; ++ i) cn2[i] = (i - 1) * i / 2;
56 while(scanf("%d%d%d", &n, &m, &p) == 3) {
57 init();
58 ans = 0;
59 dfs(1, 0);
60 printf("%lld\n", ans);
61 }
62 return 0;
63 }
64
]]>
棰樼洰澶ф剰錛氱粰瀹氫竴浜沚oard鐨勯暱搴︼紝涓浜況ail鐨勯暱搴︺傛眰鍑烘渶澶氳兘鐢╞oard鍒囧嚭鐨剅ail鏁扮洰銆?br>鏁版嵁鑼冨洿: board鏁扮洰<=50, rail鏁扮洰<=1023, rail闀垮害鑼冨洿<=128
鎬濊礬錛氫簩鍒?dfsid +鍓灊
#include <algorithm>
#include <memory.h>
using namespace std;
const int maxr = 1024;
const int maxb = 64;
int rail[maxr], board[maxb], remain[maxb];
int nrail, nboard;
int sumr[maxr], sumb[maxb];
int choice[maxr];
bool cmp(int a, int b) {
return a > b;
}
bool dfsid(int t, int n) {
if(t == n) return true;
int waste = 0;
for(int i = 0; i < nboard; ++ i) if(remain[i] < rail[0]) waste += remain[i];
if(waste + sumr[n - 1] > sumb[nboard - 1]) return false;//濡傛灉嫻垂澶鍓帀
int start = 0;
if(t > 0 && rail[n - t - 1] == rail[n - t]) start = choice[t - 1];//濡傛灉褰撳墠rail鍜屼箣鍓嶇殑rail闀垮害鐩稿悓鐩存帴浠庡墠涓涓猺ail灝濊瘯鐨刡oard寮濮?娉ㄦ剰铏界劧浠庡皬鍒板ぇ璐紝浣嗙‘瀹氳椽鐨勪釜鏁頒箣鍚庡嵈浠庡ぇ鍒板皬鎼滅儲(chǔ)
for(int i = start; i < nboard; ++ i) {
if(remain[i] >= rail[n - t - 1]) {
remain[i] -= rail[n - t - 1];
choice[t] = i;
bool ret = dfsid(t + 1, n);
remain[i] += rail[n - t - 1];
choice[t] = -1;
if(ret) return true;
}
}
return false;
}
int main()
{
freopen("fence8.in", "r", stdin);
freopen("fence8.out", "w", stdout);
scanf("%d", &nboard);
for(int i = 0; i < nboard; ++ i) {
scanf("%d", &board[i]);
remain[i] = board[i];
}
sort(board, board + nboard, cmp);//board浠庡ぇ鍒板皬灝濊瘯
scanf("%d", &nrail);
for(int i = 0; i < nrail; ++ i) scanf("%d", &rail[i]);
sort(rail, rail + nrail);//璐績(jī):灝介噺鍙栧皬鐨?br> sumb[0] = board[0], sumr[0] = rail[0];
for(int i = 1; i < nrail; ++ i) sumr[i] = sumr[i - 1] + rail[i];
for(int i = 1; i < nboard; ++ i) sumb[i] = sumb[i - 1] + board[i];
memset(choice, -1, sizeof(choice));
int low = 0, high = nrail, ans = -1;
while(sumr[high - 1] > sumb[nboard - 1]) high--;
while(low <= high) {
int mid = (low + high) >> 1;
if(dfsid(0, mid)) {
ans = mid;
low = mid + 1;
}
else high = mid - 1;
}
printf("%d\n", ans);
return 0;
}
]]>
#include <string.h>
#include <queue>
#include <iostream>
using namespace std;
const int maxnodes = 480;
const int maxlen = 1024;
const int maxchar = 4;
int child[maxnodes][maxchar];
bool danger[maxnodes];
int fail[maxnodes], nodes;
int dp[maxlen][maxnodes];
char str[maxlen];
inline int getid(char ch) {
switch(ch) {
case 'A':return 0;
case 'G':return 1;
case 'C':return 2;
case 'T':return 3;
}
return -1;
}
void insert(char *words) {
int p = 1;
for(int i = 0; words[i]; ++ i) {
int idx = getid(words[i]);
if(child[p][idx] == 0)
child[p][idx] = ++nodes;
p = child[p][idx];
if(danger[p]) break;
}
danger[p] = true;
}
bool build_trie() {
int n;
char words[30];
scanf("%d", &n);
if(n == 0) return false;
nodes = 1;
memset(child, 0, sizeof(child));
memset(danger, 0, sizeof(danger));
memset(fail, 0, sizeof(fail));
for(int i = 0; i < n; ++ i) {
scanf("%s", words);
insert(words);
}
return true;
}
void build_graph() {
queue<int> Q;
for(int i = 0; i < maxchar; ++ i) {
if(child[1][i] == 0) child[1][i] = 1;
else {
Q.push(child[1][i]);
fail[child[1][i]] = 1;
}
}
while(!Q.empty()) {
int tmp = Q.front(); Q.pop();
danger[tmp] = danger[tmp] || danger[fail[tmp]];
if(!danger[tmp]) {
for(int i = 0; i < maxchar; ++ i) {
if(child[tmp][i] == 0) child[tmp][i] = child[fail[tmp]][i];
else {
Q.push(child[tmp][i]);
fail[child[tmp][i]] = child[fail[tmp]][i];
}
}
}
}
}
void check(int &a, int b) { if(a == -1 || a > b) a = b; }
int main()
{
int cases = 0;
while(build_trie()) {
printf("Case %d: ", ++cases);
build_graph();
scanf("%s", str);
memset(dp, -1, sizeof(dp));
if(!danger[child[1][getid(str[0])]]) dp[0][child[1][getid(str[0])]] = 0;
for(int i = 0; i < maxchar; ++ i)
if(getid(str[0]) != i && !danger[child[1][i]])
dp[0][child[1][i]] = 1;
for(int i = 1; str[i]; ++ i)
for(int j = 1; j <= nodes; ++ j) {
if(dp[i-1][j] != -1) {
int idx = getid(str[i]);
if(!danger[child[j][idx]])
check(dp[i][child[j][idx]], dp[i-1][j]);
for(int k = 0; k < maxchar; ++ k)
if(idx != k && !danger[child[j][k]])
check(dp[i][child[j][k]], dp[i-1][j] + 1);
}
}
int ans = 1 << 20;
int len = strlen(str);
for(int i = 1; i <= nodes; ++ i)
if(!danger[i] && dp[len-1][i] != -1) check(ans, dp[len-1][i]);
if(ans == 1 << 20) ans = -1;
printf("%d\n",ans);
}
return 0;
}
]]>
using namespace std;
const int maxn = 10240;
int hp, n, m;
int maxhp[maxn], suma[maxn], attack[maxn], Tm[maxn], add[maxn];
int mint[maxn];
int main()
{
while(scanf("%d%d%d", &n, &m, &hp) == 3) {
memset(suma, 0, sizeof(suma));
for(int i = 1; i <= n; ++ i) {
scanf("%d", &attack[i]);
suma[i] = suma[i - 1] + attack[i];
}
memset(mint, -1, sizeof(mint));
for(int i = 0; i < m; ++ i) {
scanf("%d%d", &Tm[i], &add[i]);
if(mint[add[i]] == -1 || mint[add[i]] > Tm[i]) mint[add[i]] = Tm[i];
}
int top = 0;
for(int i = 0; i < m; ++ i)
if(mint[add[i]] == Tm[i]) {
Tm[top] = Tm[i];
add[top++] = add[i];
}
m = top;
int low = 0, high = hp, res = 0;
while(low <= high) {
int mid = (low + high) >> 1;
// cout << mid << endl << endl;
memset(maxhp, 0, sizeof(maxhp));
maxhp[0] = hp;
bool ok = true;
for(int i = 1; i <= n && ok; ++ i) {
for(int j = 0; j < m && ok; ++ j) {
if(i >= Tm[j] && maxhp[i - Tm[j]] - suma[i] + suma[i - Tm[j]] >= mid) {
maxhp[i] >?= maxhp[i - Tm[j]] - suma[i] + suma[i - Tm[j]] + add[j];
maxhp[i] <?= hp;
}
else if(i < Tm[j] && maxhp[0] - suma[i] >= mid) maxhp[i] >?= hp - suma[i];
}
if(maxhp[i] <= mid) ok = false;
// cout << maxhp[i] << ' ';
}
// cout << endl;
if(ok) {
res = mid;
low = mid + 1;
}
else high = mid - 1;
}
if(res == 0) puts("Die");
else printf("%d\n", res);
}
return 0;
}
]]>
m 1 2 3 4 5 6 7 8 9 10 11 12
mu(m) 1 -1 -1 0 -1 1 -1 0 0 1 -1 0
mobius 鍙嶆紨鍏紡1: g(m) = sigma{[d | m] * f(d) } <=> f(m) = sigma{ [d | m]*mu(d)*g(m / d)}
鍙嶆紨鍏紡2錛歡(x) = sigma{[d >= 1] * f(x / d) } <=> f(x) = sigma{ [d >= 1] * g(x / d) }
鍒╃敤瀹氫箟鐨勭Н鎬у彲鐭u()縐э細(xì)
mu(m ) = (-1)^r m = p1*p2....pr;
0 鏌恜^2 | m