Skip to content

Commit

Permalink
Codeforces Round #372
Browse files Browse the repository at this point in the history
  • Loading branch information
ftiasch committed Sep 29, 2016
1 parent 0d1b3a6 commit 64836c4
Show file tree
Hide file tree
Showing 5 changed files with 359 additions and 0 deletions.
4 changes: 4 additions & 0 deletions codeforces/715-codeforces-round-372/A.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
n = input()
print 2
for i in xrange(2, n + 1):
print i * (i + 1) * (i + 1) - i + 1
85 changes: 85 additions & 0 deletions codeforces/715-codeforces-round-372/B.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>

const int N = 1000;
const int M = 10000;
const int INF = (int)1e9 + 1;

int n, l, s, t, head[N], to[M << 1], next[M << 1], length[M], from_s[N], to_t[N];

bool solve(int pass)
{
auto distance = pass ? from_s : to_t;
auto source = pass ? s : t;
std::fill(distance, distance + n, INF);
distance[source] = 0;
std::priority_queue<std::pair<int, int>> queue;
queue.emplace(0, source);
while (!queue.empty()) {
auto t = queue.top();
queue.pop();
auto u = t.second;
if (-t.first == distance[u]) {
for (auto iterator = head[u]; ~iterator; iterator = next[iterator]) {
auto v = to[iterator];
auto& ref = length[iterator >> 1];
if (!ref) {
if (pass) {
if (from_s[u] + v[to_t] < l) {
ref = l - from_s[u] - v[to_t];
return true;
}
ref = 1;
} else {
continue;
}
}
if (distance[v] > distance[u] + ref) {
distance[v] = distance[u] + ref;
queue.emplace(-distance[v], v);
}
}
}
}
return false;
}

int main()
{
#ifdef LOCAL_JUDGE
freopen("B.in", "r", stdin);
#endif
int m;
scanf("%d%d%d%d%d", &n, &m, &l, &s, &t);
for (int i = 0; i < m << 1; ++ i) {
scanf("%d", to + i);
if (i & 1) {
scanf("%d", length + (i >> 1));
}
}
memset(head, -1, sizeof(head));
for (int i = 0; i < m << 1; ++ i) {
auto& h = head[to[i ^ 1]];
next[i] = h;
h = i;
}
solve(0);
if (s[to_t] < l) {
puts("NO");
} else {
if (s[to_t] > l && !solve(1)) {
puts("NO");
return 0;
}
puts("YES");
for (int i = 0; i < m << 1; ++ i) {
printf("%d ", to[i]);
if (i & 1) {
auto l = length[i >> 1];
printf("%d\n", l ? l : INF);
}
}
}
}
128 changes: 128 additions & 0 deletions codeforces/715-codeforces-round-372/C.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
#include <utility>

using Long = long long;

const int N = 100000;

std::pair<int, int> gcd(int a, int b)
{
if (!b) {
return {1, 0};
}
int x, y;
std::tie(y, x) = gcd(b, a % b);
return {x, y - a / b * x};
}

int n, mod, power[N + N];
Long inv10;
std::vector<std::pair<int, int>> tree[N];

using Map = std::map<int, int>;

struct M
{
M() : l(0), d(0), m(new Map()) {}

int count(int k) const
{
auto iterator = m->find(fix(k));
return iterator == m->end() ? 0 : iterator->second;
}

int eval(const std::pair<int, int>& kv) const
{
return (1LL * kv.first * power[n + l] + d) % mod;
}

int fix(int k) const
{
return 1LL * (k + mod - d) * power[n - l] % mod;
}

int size() const
{
return m->size();
}

void insert(int k, int v)
{
(*m)[fix(k)] += v;
}

int l, d;
Map* m;
};

Long intersect(const M& a, const M& b)
{
Long result = 0;
for (auto&& kv : *a.m) {
result += 1LL * kv.second * b.count(a.eval(kv));
}
return result;
}

void merge(const M& a, M& b)
{
for (auto&& kv : *a.m) {
b.insert(a.eval(kv), kv.second);
}
}

std::pair<Long, std::pair<M, M>> solve(int p, int u)
{
Long result = 0;
M down, up;
down.insert(0, 1);
up.insert(0, 1);
for (auto&& iterator : tree[u]) {
auto&& v = iterator.first;
auto&& d = iterator.second;
if (p == v) {
continue;
}
auto subtree = solve(u, v);
result += subtree.first;
auto sdown = subtree.second.first;
sdown.l --;
sdown.d = (sdown.d + d) * inv10 % mod;
auto sup = subtree.second.second;
sup.l ++;
sup.d = (sup.d * 10LL + mod - d) % mod;
if (down.size() < sdown.size()) {
std::swap(down, sdown);
std::swap(up, sup);
}
result += intersect(sdown, up) + intersect(sup, down);
merge(sdown, down);
merge(sup, up);
}
return {result, {down, up}};
}

int main()
{
#ifdef LOCAL_JUDGE
freopen("C.in", "r", stdin);
#endif
scanf("%d%d", &n, &mod);
inv10 = (gcd(10, mod).first % mod + mod) % mod;
power[n] = 1;
for (int i = 1; i < n; ++ i) {
power[n + i] = power[n + i - 1] * 10LL % mod;
power[n - i] = power[n - i + 1] * inv10 % mod;
}
for (int i = 0; i < n - 1; ++ i) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
tree[a].emplace_back(b, c);
tree[b].emplace_back(a, c);
}
std::cout << solve(-1, 0).first << std::endl;
}
44 changes: 44 additions & 0 deletions codeforces/715-codeforces-round-372/D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
def down(x, y):
return (x, y, x + 1, y)

def right(x, y):
return (x, y, x, y + 1)

t = input()
n = 0
while 3 ** n <= t:
n += 1
walls = []
for i in xrange(n):
if t % 3 < 1:
walls.append(right(1 + i, 3 + i))
if i + 1 < n:
walls.append(down(1 + i, 4 + i))
if t % 3 < 2:
walls.append(down(3 + i, 1 + i))
if i + 1 < n:
walls.append(right(4 + i, 1 + i))
t /= 3
walls.append(right(1 + n, 2 + n))
walls.append(right(2 + n, 2 + n))
walls.append(down(2 + n, 1 + n))
walls.append(down(2 + n, 2 + n))
for i in xrange(n - 2):
walls.append(right(1 + i, 5 + i))
walls.append(down(5 + i, 1 + i))
assert t == 0
print n + 3, n + 3
print len(walls)
for wall in walls:
print ' '.join(map(str, wall))
# m = n + 3
# grid = [[' '] * (2 * m + 1) for _ in xrange(2 * m + 1)]
# for i in xrange(m + 1):
# for j in xrange(m + 1):
# grid[2 * i][2 * j] = '.'
# for wall in walls:
# if wall[0] == wall[2]:
# grid[2 * wall[0] - 1][2 * wall[1]] = '|'
# else:
# grid[2 * wall[0]][2 * wall[1] - 1] = '-'
# print "\n".join(map(lambda r: ''.join(r), grid))
98 changes: 98 additions & 0 deletions codeforces/715-codeforces-round-372/E.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include <algorithm>
#include <cstdio>
#include <cstring>

const int N = 251;
const int MOD = 998244353;

int a[N], b[N], go[N], rgo[N], count[4], ways[N];
bool visited[N];

void update(int& x, int a)
{
x += a;
if (x >= MOD) {
x -= MOD;
}
}

int main()
{
#ifdef LOCAL_JUDGE
freopen("E.in", "r", stdin);
#endif
int n;
while (scanf("%d", &n) == 1) {
for (int i = 1; i <= n; ++ i) {
scanf("%d", a + i);
}
memset(go, -1, sizeof(go));
memset(rgo, -1, sizeof(rgo));
for (int i = 1; i <= n; ++ i) {
scanf("%d", b + i);
if (a[i]) {
go[a[i]] = b[i];
}
if (b[i]) {
rgo[b[i]] = a[i];
}
}
memset(count, 0, sizeof(count));
memset(visited, 0, sizeof(visited));
for (int s = 1; s <= n; ++ s) {
if (rgo[s] > 0) {
continue;
}
int t = s;
visited[s] = true;
while (go[t] > 0) {
visited[t = go[t]] = true;
}
count[!rgo[s] | !go[t] << 1] ++;
}
int cycles = 0;
for (int s = 1; s <= n; ++ s) {
if (visited[s]) {
continue;
}
cycles ++;
for (int v = s; !visited[v]; v = go[v]) {
visited[v] = true;
}
}
// printf("! %d %d %d %d %d\n", cycles, count[0], count[1], count[2], count[3]);
memset(ways, 0, sizeof(ways));
ways[0] = 1;
int total = 0;
for (int i = 1; i <= n; ++ i) {
if (!a[i] && !b[i]) {
ways[0] = 1LL * ways[0] * (++ total) % MOD;
}
}
total = 0;
for (int i = 0; i < 4; ++ i) {
for (int j = 0; j < count[i]; ++ j) {
for (int k = n; k >= 0; -- k) {
int new_ways = 0;
if (k && i < 3) {
update(new_ways, ways[k - 1]);
}
int w = 0;
if (i < 2) {
w = total;
} else if (i == 2) {
w = total - count[1];
} else {
w = std::max(count[0] - j, 0);
}
update(new_ways, 1LL * w * ways[k] % MOD);
ways[k] = new_ways;
}
total ++;
}
}
for (int i = 0; i < n; ++ i) {
printf("%d%c", i + cycles <= n ? ways[n - i - cycles] : 0, " \n"[i == n - 1]);
}
}
}

0 comments on commit 64836c4

Please sign in to comment.