Mischievous Problem Setter
模拟。
#include <bits/stdc++.h>
using namespace std;
int main() {
#ifdef wxh010910
freopen("input.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int tt;
cin >> tt;
for (int qq = 1; qq <= tt; ++qq) {
int n, m;
cin >> n >> m;
vector<pair<int, int>> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i].first;
}
for (int i = 0; i < n; ++i) {
cin >> a[i].second;
}
sort(a.begin(), a.end());
int ans = 0;
while (ans < n && m >= a[ans].second) {
m -= a[ans++].second;
}
cout << "Case " << qq << ": " << ans << "\n";
}
return 0;
}
Balance of the Force
建出图,如果图不是二分图,则无解。否则枚举最大值,用堆维护最小值的最大可能值。
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
class heap {
priority_queue<int, vector<int>, greater<int>> p, q;
public:
void push(int x) {
p.push(x);
}
void pop(int x) {
q.push(x);
}
int top() {
while (!q.empty() && p.top() == q.top()) {
p.pop();
q.pop();
}
return p.top();
}
};
int main() {
#ifdef wxh010910
freopen("input.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int tt;
cin >> tt;
for (int qq = 1; qq <= tt; ++qq) {
int n, m;
cin >> n >> m;
vector<vector<int>> adj(n);
for (int i = 0; i < m; ++i) {
int from, to;
cin >> from >> to;
--from;
--to;
adj[from].push_back(to);
adj[to].push_back(from);
}
vector<vector<int>> a(n, vector<int>(2));
for (int i = 0; i < n; ++i) {
cin >> a[i][0] >> a[i][1];
}
bool no_solution = false;
vector<int> sz(n);
vector<int> cur(n);
vector<int> min_id(n);
vector<int> color(n, -1);
vector<vector<int>> cnt(n, vector<int>(2));
vector<vector<int>> minv(n, vector<int>(2, inf));
heap h;
for (int i = 0; i < n; ++i) {
if (color[i] == -1) {
h.push(cur[i] = -inf);
queue<int> q;
color[i] = 0;
min_id[i] = i;
++sz[i];
q.push(i);
while (!q.empty()) {
int x = q.front();
q.pop();
minv[i][color[x]] = min(minv[i][color[x]], a[x][0]);
minv[i][!color[x]] = min(minv[i][!color[x]], a[x][1]);
for (auto y : adj[x]) {
if (color[y] == -1) {
color[y] = !color[x];
min_id[y] = i;
++sz[i];
q.push(y);
} else if (color[y] == color[x]) {
no_solution = true;
break;
}
}
}
if (no_solution) {
break;
}
}
}
if (no_solution) {
cout << "Case " << qq << ": IMPOSSIBLE" << "\n";
continue;
}
int ans = inf;
vector<pair<int, int>> events(n * 2);
for (int i = 0; i < n; ++i) {
events[i * 2] = make_pair(a[i][0], i);
events[i * 2 + 1] = make_pair(a[i][1], i + n);
}
sort(events.begin(), events.end());
for (auto p : events) {
int x = p.second;
if (x >= n) {
x -= n;
if (++cnt[min_id[x]][!color[x]] == sz[min_id[x]]) {
h.pop(cur[min_id[x]]);
cur[min_id[x]] = max(cur[min_id[x]], minv[min_id[x]][!color[x]]);
h.push(cur[min_id[x]]);
}
} else {
if (++cnt[min_id[x]][color[x]] == sz[min_id[x]]) {
h.pop(cur[min_id[x]]);
cur[min_id[x]] = max(cur[min_id[x]], minv[min_id[x]][color[x]]);
h.push(cur[min_id[x]]);
}
}
ans = min(ans, p.first - h.top());
}
cout << "Case " << qq << ": " << ans << "\n";
}
return 0;
}
GCD Land
记 m m m 为 n 2 \frac{n}{2} 2n ,令 m m m 的编号 x x x 为不超过 m m m 的素数的乘积,那么此时只有 m + 1 m+1 m+1 和 m − 1 m-1 m−1 没有连起来;考虑去掉 m m m 以内的最大的两个质数 p , q p, q p,q ,用它们去连 1 1 1 和 − 1 -1 −1 (即 x − 1   m o d   p = 0 , x + 1   m o d   q = 0 x-1\bmod p=0, x+1\bmod q=0 x−1modp=0,x+1modq=0 ),此时 m − p , m − q , m + p , m + q m-p, m-q, m+p, m+q m−p,m−q,m+p,m+q 没有被连起来;注意到我们还没有用大于 m m m 的质数,用这些质数连起来,最后CRT合并即可。这个做法需要特判 n ≤ 38 n\le 38 n≤38 的数据。
to_multiply = []
table = [-1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2183, 27828, 27827, 87889, 87889, 171053, 171053, 323509, 127373, 323509, 151061, 151061, 151061, 151060, 151059, 151058, 151057, 672540170261, 672540170261, 2101641443861, 2101641443861, 4152621523030]
def inv(a, md):
b, u, v = md, 0, 1
while a:
t = b / a
a, b = b - t * a, a
v, u = u - t * v, v
if u < 0:
u += md
return u
def crt(m, a):
mm, aa = m[0], a[0]
for i in range(1, len(m)):
mm, aa = mm * m[i], (aa * m[i] * inv(m[i], mm) + a[i] * mm * inv(mm, m[i])) % (mm * m[i])
return aa
def multiply_all(l, r):
if l > r:
return 1
elif l == r:
return to_multiply[l]
else:
m = (l + r) / 2
return multiply_all(l, m) * multiply_all(m + 1, r)
tt = int(raw_input())
for qq in range(1, tt + 1):
n = int(raw_input())
if n < 39:
ans = table[n]
else:
prime = [True] * (n + 1)
for i in range(2, n + 1):
for j in range(i + i, n + 1, i):
prime[j] = False
m = (n + 1) / 2
to_multiply = []
for i in range(2, m):
if prime[i]:
to_multiply.append(i)
p, q = to_multiply[-2], to_multiply[-1]
to_multiply = to_multiply[:-2]
if m * 2 == n and prime[m]:
to_multiply.append(m)
r = []
for i in range(n - m + 1, n):
if prime