国庆挖坑
10.1 2014鞍山
10.2 四汆省赛
10.3 ???
10.4 CCPC长春
HDU 5921 Binary Indexed Tree
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long LL; 7 const LL mod = 1e9 + 7; 8 LL p[66], f[66][2][2], g[66][2][2]; 9 int nn[66]; 10 11 LL cal(int len) 12 { 13 memset(f, 0, sizeof(f)); 14 memset(g, 0, sizeof(g)); 15 f[0][1][1] = 1; 16 for(int i = 0; i < len; i++) 17 for(int p = 0; p <= 1; p++) 18 for(int q = 0; q <= 1; q++) 19 { 20 if(!f[i][p][q]) continue; 21 for(int nl = 0; nl <= 1; nl++) 22 for(int nr = 0; nr <= 1; nr++) 23 { 24 if(p && nl > nr) continue; 25 if(q && nr > nn[i+1]) continue; 26 int np = p && nl == nr; 27 int nq = q && nr == nn[i+1]; 28 f[i+1][np][nq] = (f[i+1][np][nq] + f[i][p][q]) % mod; 29 if(!np) g[i+1][np][nq] = (g[i+1][np][nq] + g[i][p][q] + f[i][p][q] * (nl + nr)) % mod; 30 } 31 } 32 return (g[len][0][0] + g[len][0][1]) % mod; 33 } 34 35 int main(void) 36 { 37 p[0] = 1LL; 38 for(int i = 1; i < 66; i++) p[i] = p[i-1] * 2 % mod; 39 int T; 40 scanf("%d", &T); 41 for(int kase = 1; kase <= T; kase++) 42 { 43 LL n; 44 scanf("%lld", &n); 45 int len = 0; 46 while(n) 47 { 48 nn[++len] = n % 2; 49 n /= 2; 50 } 51 reverse(nn + 1, nn + 1 + len); 52 printf("Case #%d: %lld\n", kase, cal(len)); 53 } 54 return 0; 55 }
10.5 台湾
10.6 东北
10.7 PKU
A.Escape
大概需要预处理组合数,然后认真枚举一下从哪个方向进终点,转了几圈,在什么位置转弯用组合数算。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 typedef long long LL; 5 const LL mod = 100000007; 6 using namespace std; 7 LL C[2222][2222]; 8 9 int main(void) 10 { 11 for(int i = 0; i < 2222; i++) C[i][0] = C[i][i] = 1; 12 for(int i = 2; i < 2222; i++) 13 for(int j = 1; j < i; j++) 14 C[i][j] = (C[i-1][j-1] + C[i-1][j]) % mod; 15 16 int T; 17 scanf("%d", &T); 18 while(T--) 19 { 20 int X, Y, x, y, r; 21 scanf("%d %d %d %d", &X, &Y, &x, &y); 22 LL ans = 1; 23 24 r = min(min(x, X - x), min(y, Y - y)); 25 for(int i = 1; i <= r; i++) ans = (ans + C[x-1][i-1] * C[X-x][i] % mod * C[y][i] % mod * C[Y-y][i]) % mod; 26 27 r = min(min(x - 1, X - x), min(y, Y - y)); 28 for(int i = 1; i <= r; i++) ans = (ans + C[x-1][i] * C[X-x][i] % mod * C[y][i] % mod * C[Y-y][i]) % mod; 29 30 if(x && y != Y) ans = (ans + Y - y) % mod; 31 r = min(min(x - 1, X - x), min(y, Y - y - 1)); 32 for(int i = 1; i <= r; i++) ans = (ans + C[x-1][i] * C[X-x][i] % mod * C[y][i] % mod * C[Y-y][i+1]) % mod; 33 34 if(x && y != Y && x != X) ans = (ans + (Y - y) * (X - x)) % mod; 35 r = min(min(x - 1, X - x - 1), min(y, Y - y - 1)); 36 for(int i = 1; i <= r; i++) ans = (ans + C[x-1][i] * C[X-x][i+1] % mod * C[y][i] % mod * C[Y-y][i+1]) % mod; 37 38 printf("%lld\n", ans); 39 } 40 return 0; 41 }
因为速度一样所以在路途中能打到等价于能蹲在终点等他过来打到。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 7 struct E 8 { 9 double t, s, d; 10 E(double _t = 0, double _s = 0, double _d = 0): t(_t), s(_s), d(_d){} 11 friend bool operator < (E A, E B) 12 { 13 return A.t < B.t; 14 } 15 } e[111]; 16 17 double dis(double x, double y) 18 { 19 return sqrt((x - 100) * (x - 100) + y * y); 20 } 21 22 int main(void) 23 { 24 int N; 25 while(~scanf("%d", &N)) 26 { 27 for(int i = 1; i <= N; i++) 28 { 29 double x, y, s, r, d; 30 scanf("%lf%lf%lf%lf%lf", &x, &y, &s, &r, &d); 31 e[i].t = dis(x, y) - r; 32 e[i].s = s, e[i].d = d; 33 } 34 sort(e + 1, e + 1 + N); 35 double HP; 36 scanf("%lf", &HP); 37 double now = 100; 38 for(int i = 1; i <= N; i++) 39 if(e[i].t <= now) now += e[i].s, HP -= e[i].d; 40 puts(HP <= 0 ? "Danger!" : "Safe!"); 41 } 42 return 0; 43 }
打牌一下转移是换base或者消一张牌中选收益最大的去转移。不知道为何longdouble才过。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 int L[15] = { 1, 3, 4, 6, 7, 8, 10, 11, 12, 13, 0, 0, 0, 0, 0 }; 7 int R[15] = { 2, 4, 5, 7, 8, 9, 11, 12, 13, 14, 0, 0, 0, 0, 0 }; 8 long double dp[1<<15][101][13]; 9 bool vis[1<<15][101][13]; 10 int n, m, P, Q, G[6][6]; 11 12 long double cal(int mask, int cnt, int base) 13 { 14 if(vis[mask][cnt][base]) return dp[mask][cnt][base]; 15 vis[mask][cnt][base] = 1; 16 17 if(!mask) return dp[mask][cnt][base] = 0.00; 18 19 long double ret1 = 0.00, ret2 = -1e9; 20 21 if(cnt) for(int i = 0; i < 13; i++) ret1 += (cal(mask, cnt - 1, i) - Q) / 13; 22 23 int id = 0; 24 for(int i = 1; i <= n; i++) 25 for(int j = 1; j <= i; j++, id++) 26 { 27 if(G[i][j] != (base + 1) % 13 && G[i][j] != (base + 12) % 13) continue; 28 if(!((1 << id) & mask)) continue; 29 if(L[id] && ((1 << L[id]) & mask)) continue; 30 if(R[id] && ((1 << R[id]) & mask)) continue; 31 ret2 = max(ret2, cal(mask ^ (1 << id), cnt, G[i][j]) + P); 32 } 33 34 return dp[mask][cnt][base] = max(ret1, ret2); 35 } 36 37 int main(void) 38 { 39 while(~scanf("%d %d", &n, &m)) 40 { 41 if(!n && !m) break; 42 43 for(int i = 0; i < (1 << (n * (n + 1) / 2)); i++) 44 for(int j = 0; j <= m; j++) 45 for(int k = 0; k < 13; k++) 46 vis[i][j][k] = 0; 47 48 for(int i = 1; i <= n; i++) 49 for(int j = 1; j <= i; j++) 50 scanf("%d", &G[i][j]), G[i][j]--; 51 52 int X; 53 scanf("%d%d%d", &P, &Q, &X); 54 printf("%.2f\n", (double) cal((1 << (n * (n + 1) / 2)) - 1, m, X - 1)); 55 } 56 return 0; 57 }
预处理区间点数和每个对角线上的点,再双指针扫每条对角线就n2了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 int yy[1111], xx[1111]; 8 int cnt[2222][2222]; 9 vector<int> vec[4444]; 10 11 bool ok(int id, int i, int j) 12 { 13 int x1 = vec[id+2222][i], y1 = x1 + id; 14 int x2 = vec[id+2222][j], y2 = x2 + id; 15 int num = cnt[x2][y2]; 16 if(x1) num -= cnt[x1-1][y2]; 17 if(y1) num -= cnt[x2][y1-1]; 18 if(x1 && y1) num += cnt[x1-1][y1-1]; 19 return num > 0; 20 } 21 22 int main(void) 23 { 24 int n1, n2, n3; 25 while(~scanf("%d %d %d", &n1, &n2, &n3)) 26 { 27 memset(cnt, 0, sizeof(cnt)); 28 for(int i = 1; i <= n1; i++) scanf("%d", yy + i); 29 for(int i = 1; i <= n2; i++) scanf("%d", xx + i); 30 for(int i = 1; i <= n3; i++) 31 { 32 int px, py; 33 scanf("%d %d", &px, &py); 34 cnt[px][py]++; 35 } 36 for(int i = 0; i < 2222; i++) 37 for(int j = 0; j < 2222; j++) 38 { 39 if(i) cnt[i][j] += cnt[i-1][j]; 40 if(j) cnt[i][j] += cnt[i][j-1]; 41 if(i && j) cnt[i][j] -= cnt[i-1][j-1]; 42 } 43 for(int i = -2222; i < 2222; i++) vec[i+2222].clear(); 44 for(int i = 1; i <= n1; i++) 45 for(int j = 1; j <= n2; j++) 46 vec[yy[i] - xx[j] + 2222].push_back(xx[j]); 47 int ans = 0; 48 for(int i = -2222; i < 2222; i++) 49 { 50 sort(vec[i+2222].begin(), vec[i+2222].end()); 51 int sz = vec[i+2222].size(); 52 int p = 0; 53 for(int j = 0; j < sz; j++) 54 { 55 while(!ok(i, j, p)) 56 { 57 p++; 58 if(p == sz) break; 59 } 60 if(p == j) p++; 61 if(p < sz) ans += sz - p; 62 else break; 63 } 64 } 65 printf("%d\n", ans); 66 } 67 return 0; 68 }
n2随便暴力就可以了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 int nxt[1111][26], ok[1111]; 7 8 int vis1[1111], vis2[1111], vis3[1111]; 9 vector<int> vec1, vec2, vec3; 10 bool dfs1(int st, int x) 11 { 12 vis1[x] = 1; 13 for(int i = 0; i < 26; i++) 14 { 15 if(nxt[x][i] == -1) continue; 16 int to = nxt[x][i]; 17 if(to == st) {vec1.push_back(i); return true;} 18 if(!vis1[to]) 19 { 20 vis1[to] = 1; 21 vec1.push_back(i); 22 if(dfs1(st, to)) return true; 23 vec1.pop_back(); 24 } 25 } 26 return false; 27 } 28 29 bool dfs2(int x, int t) 30 { 31 vis2[x] = 1; 32 for(int i = 0; i < 26; i++) 33 { 34 if(nxt[x][i] == -1) continue; 35 int to = nxt[x][i]; 36 if(to == t) {vec2.push_back(i); return true;} 37 if(!vis2[to]) 38 { 39 vis2[to] = 1; 40 vec2.push_back(i); 41 if(dfs2(to, t)) return true; 42 vec2.pop_back(); 43 } 44 } 45 return false; 46 } 47 48 bool dfs3(int x) 49 { 50 vis3[x] = 1; 51 for(int i = 0; i < 26; i++) 52 { 53 if(nxt[x][i] == -1) continue; 54 int to = nxt[x][i]; 55 if(ok[to]) {vec3.push_back(i); return true;} 56 if(!vis3[to]) 57 { 58 vis3[to] = 1; 59 vec3.push_back(i); 60 if(dfs3(to)) return true; 61 vec3.pop_back(); 62 } 63 } 64 return false; 65 } 66 67 int main(void) 68 { 69 int n, s, m, k; 70 scanf("%d %d %d", &n, &s, &m); 71 memset(nxt, -1, sizeof(nxt)); 72 for(int i = 1; i <= m; i++) 73 { 74 int u, v; 75 char str[11]; 76 scanf("%d %s %d", &u, str, &v); 77 nxt[u][str[0]-'a'] = v; 78 } 79 scanf("%d", &k); 80 for(int i = 1; i <= k; i++) 81 { 82 int x; 83 scanf("%d", &x); 84 ok[x] = 1; 85 } 86 87 int yes = 0; 88 for(int i = 1; i <= n; i++) 89 { 90 memset(vis1, 0, sizeof(vis1)); 91 memset(vis2, 0, sizeof(vis2)); 92 memset(vis3, 0, sizeof(vis3)); 93 vec1.clear(); vec2.clear(); vec3.clear(); 94 if(dfs1(i, i) && dfs2(s, i) && dfs3(i)) 95 { 96 yes = 1; 97 for(int j = 0; j < vec2.size(); j++) printf("%c", 'a' + vec2[j]); 98 putchar('('); 99 for(int j = 0; j < vec1.size(); j++) printf("%c", 'a' + vec1[j]); 100 putchar(')'); 101 for(int j = 0; j < vec3.size(); j++) printf("%c", 'a' + vec3[j]); 102 puts(""); 103 break; 104 } 105 } 106 if(!yes) puts("*"); 107 return 0; 108 }