Skip to content

Commit 5f0d2fc

Browse files
2019.11.23
1 parent 30564f4 commit 5f0d2fc

File tree

3 files changed

+213
-2
lines changed

3 files changed

+213
-2
lines changed

part2/agc030_f.cpp

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#include <cstdio>
2+
#include <cstring>
3+
#include <cstdlib>
4+
#include <cmath>
5+
#include <ctime>
6+
#include <cctype>
7+
8+
#include <algorithm>
9+
#include <random>
10+
#include <bitset>
11+
#include <queue>
12+
#include <functional>
13+
#include <set>
14+
#include <map>
15+
#include <vector>
16+
#include <chrono>
17+
#include <iostream>
18+
#include <limits>
19+
#include <numeric>
20+
21+
#define LOG(FMT...) fprintf(stderr, FMT)
22+
23+
using namespace std;
24+
25+
typedef long long ll;
26+
typedef unsigned long long ull;
27+
28+
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
29+
30+
template <class T>
31+
istream& operator>>(istream& is, vector<T>& v) {
32+
for (T& x : v)
33+
is >> x;
34+
return is;
35+
}
36+
37+
template <class T>
38+
ostream& operator<<(ostream& os, const vector<T>& v) {
39+
if (!v.empty()) {
40+
os << v.front();
41+
for (int i = 1; i < v.size(); ++i)
42+
os << ' ' << v[i];
43+
}
44+
return os;
45+
}
46+
47+
const int P = 1000000007;
48+
49+
void add(int& x, int y) {
50+
if ((x += y) >= P)
51+
x -= P;
52+
}
53+
54+
void sub(int& x, int y) {
55+
if ((x -= y) < 0)
56+
x += P;
57+
}
58+
59+
int norm(int x) { return x >= P ? x - P : x; }
60+
61+
int main() {
62+
#ifdef LBT
63+
freopen("test.in", "r", stdin);
64+
int nol_cl = clock();
65+
#endif
66+
ios::sync_with_stdio(false);
67+
cin.tie(nullptr);
68+
69+
int n;
70+
cin >> n;
71+
vector<int> a(n * 2), pos(n * 2, -1);
72+
cin >> a;
73+
for (int i = 0; i < n * 2; ++i)
74+
if (a[i] != -1)
75+
pos[--a[i]] = i;
76+
int empties = 0;
77+
for (int i = 0; i < n; ++i)
78+
if (a[i * 2] == -1 && a[i * 2 + 1] == -1)
79+
++empties;
80+
vector<vector<int>> dp(n + 1, vector<int>(n + 1));
81+
dp[0][0] = 1;
82+
for (int i = 0; i < n * 2; ++i) {
83+
if (pos[i] != -1 && a[pos[i] ^ 1] != -1)
84+
continue;
85+
vector<vector<int>> newDp(n + 1, vector<int>(n + 1));
86+
if (pos[i] == -1) {
87+
for (int j = 0; j <= n; ++j)
88+
for (int k = 0; k <= n; ++k) {
89+
if (k < n)
90+
add(newDp[j][k + 1], dp[j][k]);
91+
if (j < n)
92+
add(newDp[j + 1][k], dp[j][k]);
93+
if (k)
94+
add(newDp[j][k - 1], dp[j][k]);
95+
}
96+
} else {
97+
for (int j = 0; j <= n; ++j)
98+
for (int k = 0; k <= n; ++k) {
99+
if (k < n)
100+
add(newDp[j][k + 1], dp[j][k]);
101+
if (j)
102+
add(newDp[j - 1][k], dp[j][k] * (ll)j % P);
103+
}
104+
}
105+
dp = newDp;
106+
}
107+
int ans = dp[0][0];
108+
for (int i = 1; i <= empties; ++i)
109+
ans = ans * (ll)i % P;
110+
cout << ans << '\n';
111+
112+
#ifdef LBT
113+
LOG("Time: %dms\n", int ((clock()
114+
-nol_cl) / (double)CLOCKS_PER_SEC * 1000));
115+
#endif
116+
return 0;
117+
}

part2/cf605E.cpp

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#include <cstdio>
2+
#include <cstring>
3+
#include <cstdlib>
4+
#include <cmath>
5+
#include <ctime>
6+
#include <cctype>
7+
8+
#include <algorithm>
9+
#include <random>
10+
#include <bitset>
11+
#include <queue>
12+
#include <functional>
13+
#include <set>
14+
#include <map>
15+
#include <vector>
16+
#include <chrono>
17+
#include <iostream>
18+
#include <limits>
19+
#include <numeric>
20+
21+
#define LOG(FMT...) fprintf(stderr, FMT)
22+
23+
using namespace std;
24+
25+
typedef long long ll;
26+
typedef unsigned long long ull;
27+
28+
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
29+
30+
template <class T>
31+
istream& operator>>(istream& is, vector<T>& v) {
32+
for (T& x : v)
33+
is >> x;
34+
return is;
35+
}
36+
37+
template <class T>
38+
ostream& operator<<(ostream& os, const vector<T>& v) {
39+
if (!v.empty()) {
40+
os << v.front();
41+
for (int i = 1; i < v.size(); ++i)
42+
os << ' ' << v[i];
43+
}
44+
return os;
45+
}
46+
47+
const int N = 1010;
48+
49+
int n;
50+
double p[N][N];
51+
bool vis[N];
52+
double ans[N], rest[N], sum[N];
53+
54+
int main() {
55+
#ifdef LBT
56+
freopen("test.in", "r", stdin);
57+
int nol_cl = clock();
58+
#endif
59+
ios::sync_with_stdio(false);
60+
cin.tie(nullptr);
61+
62+
scanf("%d", &n);
63+
for (int i = 1; i <= n; ++i)
64+
for (int j = 1; j <= n; ++j) {
65+
int k;
66+
scanf("%d", &k);
67+
p[i][j] = k * 0.01;
68+
}
69+
fill(rest + 1, rest + n + 1, 1);
70+
fill(ans + 1, ans + n, 1e9);
71+
for (int rep = 1; rep < n; ++rep) {
72+
int u = -1;
73+
for (int i = 1; i <= n; ++i)
74+
if (!vis[i] && (u == -1 || ans[u] > ans[i]))
75+
u = i;
76+
vis[u] = true;
77+
for (int i = 1; i <= n; ++i)
78+
if (!vis[i]) {
79+
sum[i] += rest[i] * p[i][u] * ans[u];
80+
rest[i] *= (1 - p[i][u]);
81+
if (rest[i] != 1)
82+
ans[i] = (1 + sum[i]) / (1 - rest[i]);
83+
}
84+
}
85+
printf("%.15f\n", ans[1]);
86+
87+
#ifdef LBT
88+
LOG("Time: %dms\n", int ((clock()
89+
-nol_cl) / (double)CLOCKS_PER_SEC * 1000));
90+
#endif
91+
return 0;
92+
}

part2/checklist.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
- [x] agc030_d
4545
- 记 $f(x, y, 0/1)$ 表示 $(x, y)$ 位置组成的是严格顺序对或逆序对的概率。
4646
- [ ] agc030_e
47-
- [ ] agc030_f
47+
- [x] agc030_f
48+
- 考虑从小到大决定每个数的位置,那么一个数如果作为最小值要么被放在一个没有被钦定过数的格子里,要么被放在一个被钦定了一个数的格子里,考虑在最初分类的时候把空的先视为无序,$f(i, j)$ 表示还剩下 $i$ 个空的格子已经被放了一个数,$j$ 个数确定要被放在和别的钦定的数在一起但是还没确定具体位置。
4849
- [x] agc031_d
4950
- 可以发现答案可以表示为一个 $a^{\lfloor k / 6\rfloor} b_{k \bmod 6} a^{-\lfloor k / 6\rfloor}$。
5051
- [ ] agc031_e
@@ -176,7 +177,8 @@
176177
- [ ] cf594E
177178
- [x] cf603E
178179
- LCT 维护最小生成森林顺便子树大小,另外每次看权值最大的边能不能删掉。
179-
- [ ] cf605E
180+
- [x] cf605E
181+
- 假设每个点的期望答案以及确定,那么策略显然是到开启的虫洞能到达的最早的位置,因此每次维护预计答案,每轮迭代会确定一个新的点,用来更新未确定的点即可,要维护一些中间信息来保证复杂度。
180182
- [ ] cf607E
181183
- [ ] cf611G
182184
- [x] cf611H

0 commit comments

Comments
 (0)