Skip to content

Commit

Permalink
QOJ: The 2nd Universal Cup. Stage 22: Hangzhou
Browse files Browse the repository at this point in the history
  • Loading branch information
Macesuted committed Sep 6, 2024
1 parent c37b052 commit e514a8a
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 5 deletions.
69 changes: 69 additions & 0 deletions QOJ/8236.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* @file 8236.cpp
* @author Macesuted (i@macesuted.moe)
* @date 2024-09-05
*
* @copyright Copyright (c) 2024
*
*/

#include <bits/stdc++.h>
using namespace std;

#define maxn 3005

typedef tuple<int, int, int> tiii;

const int way[2][4] = {{0, 0, +1, -1}, {+1, -1, 0, 0}};

int a[maxn][maxn], dist[maxn][maxn];
bool vis[maxn][maxn];

void solve(void) {
int n, m, k, sx, sy;
cin >> n >> m >> k;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) a[i][j] = 0, dist[i][j] = 1e9, vis[i][j] = false;
for (int i = 1, x, y; i <= k; i++) {
cin >> x >> y, a[x][y] = k - i + 1;
if (i == 1) sx = x, sy = y;
}
for (int i = 1; i <= n; i++) {
string s;
cin >> s;
for (int j = 1; j <= m; j++)
if (s[j - 1] == '#') a[i][j] = 1e9;
}

priority_queue<tiii, vector<tiii>, greater<tiii>> que;
que.emplace(dist[sx][sy] = 0, sx, sy);
while (!que.empty()) {
auto [d, x, y] = que.top();
que.pop();
if (vis[x][y]) continue;
vis[x][y] = true;
for (int t = 0; t < 4; t++) {
int tx = x + way[0][t], ty = y + way[1][t];
if (tx < 1 || tx > n || ty < 1 || ty > m) continue;
int v = max(dist[x][y] + 1, a[tx][ty]);
if (dist[tx][ty] > v) que.emplace(dist[tx][ty] = v, tx, ty);
}
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (dist[i][j] == 1e9) dist[i][j] = 0;
uint64_t ans = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) ans += (uint64_t)dist[i][j] * (uint64_t)dist[i][j];
cout << ans << endl;
return;
}

int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

int _ = 1;
while (_--) solve();

return 0;
}
113 changes: 113 additions & 0 deletions QOJ/8237.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/**
* @file 8237.cpp
* @author Macesuted (i@macesuted.moe)
* @date 2024-09-05
*
* @copyright Copyright (c) 2024
*
*/

#include <bits/stdc++.h>
using namespace std;

#define maxn 1000005
#define mod 1000000007

int64_t Mod(int64_t x) { return x >= mod ? x - mod : x; }

int64_t qpow(int64_t a, int64_t x) {
int64_t ans = 1;
while (x) {
if (x & 1) ans = ans * a % mod;
a = a * a % mod, x >>= 1;
}
return ans;
}
int64_t inv(int64_t a) { return qpow(a, mod - 2); }

const int inv2 = inv(2);

int a[maxn], w[maxn], fa[maxn], indeg[maxn];
int64_t f[maxn], fac[maxn], ifac[maxn];
vector<int> graph[maxn];

void solve(void) {
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i], graph[i].clear(), f[i] = indeg[i] = 0;
for (int i = 1; i <= n; i++) cin >> fa[i], graph[fa[i]].push_back(i), indeg[fa[i]]++;
for (int i = 1; i <= n; i++) cin >> w[i];

vector<int> lis;
queue<int> que;
for (int i = 1; i <= n; i++)
if (!indeg[i]) que.push(i);
while (!que.empty()) {
int p = que.front();
que.pop();
lis.push_back(p);
if (!--indeg[fa[p]]) que.push(fa[p]);
}
reverse(lis.begin(), lis.end());

for (int i = 1; i <= n; i++) {
if (!indeg[i]) continue;
vector<int> ring;
int tp = i;
ring.push_back(tp), tp = fa[tp], indeg[tp]--;
while (tp != i) ring.push_back(tp), tp = fa[tp], indeg[tp]--;
reverse(ring.begin(), ring.end());

if (ring.size() == 1) continue;

int m = ring.size(), p = -1;

for (int i = 0; i < m && p == -1; i++) {
int pre = (i + m - 1) % m;
if (a[ring[pre]] > a[ring[i]] || a[ring[pre]] + w[ring[pre]] <= a[ring[i]]) {
p = i;
break;
}
}

if (p == -1) continue;

if (a[fa[ring[p]]] > a[ring[p]]) f[ring[p]] = 1;
for (int i = (p + 1) % m; i != p; i = (i + 1) % m) {
int p = ring[i];
if (a[fa[p]] > a[p])
f[p] = 1;
else if (a[fa[p]] + w[fa[p]] > a[p] && f[fa[p]])
f[p] = f[fa[p]] + 1;
else
f[p] = 0;
}
}

for (auto p : lis)
if (a[fa[p]] > a[p])
f[p] = 1;
else if (a[fa[p]] + w[fa[p]] > a[p] && f[fa[p]])
f[p] = f[fa[p]] + 1;
else
f[p] = 0;

for (int i = 1; i <= n; i++) cout << (a[i] + (f[i] ? ifac[f[i]] : 0) * w[i]) % mod << ' ';
cout << endl;
return;
}

int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);

fac[0] = ifac[0] = 1;
for (int i = 1; i < maxn; i++) fac[i] = fac[i - 1] * i % mod;
ifac[maxn - 1] = inv(fac[maxn - 1]);
for (int i = maxn - 2; i; i--) ifac[i] = ifac[i + 1] * (i + 1) % mod;

int _ = 1;
cin >> _;
while (_--) solve();

return 0;
}
9 changes: 6 additions & 3 deletions templates/Data Structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class STList {
void build(int a[]) {
for (int i = 1; i <= n; i++) list[0][i] = a[i];
for (int j = 1; j <= lg[n]; j++)
for (int i = 1; i + (1 << j) - 1 <= n; i++) list[j][i] = max(list[j - 1][i], list[j - 1][i + (1 << (j - 1))]);
for (int i = 1; i + (1 << j) - 1 <= n; i++)
list[j][i] = max(list[j - 1][i], list[j - 1][i + (1 << (j - 1))]);
return;
}
int query(int l, int r) {
Expand Down Expand Up @@ -196,9 +197,9 @@ class SegmentTree {
## Fhq Treap

```cpp
mt19937 rnd;
class FhqTreap {
private:
static mt19937 rnd;

struct Node {
Node *l, *r;
Expand Down Expand Up @@ -237,7 +238,9 @@ class FhqTreap {
}

public:
FhqTreap(void) { rnd.seed(chrono::system_clock::now().time_since_epoch().count()), root = nullptr; }
FhqTreap(void) {
rnd.seed(chrono::system_clock::now().time_since_epoch().count()), root = nullptr;
}
void insert(int x) {
Node* tr = nullptr;
splitV(root, root, tr, x);
Expand Down
8 changes: 6 additions & 2 deletions templates/Graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ class Dinic {
}

public:
void resize(int _n) { return graph.resize((n = _n) + 1), cur.resize(n + 1), dist.resize(n + 1); }
void resize(int _n) {
return graph.resize((n = _n) + 1), cur.resize(n + 1), dist.resize(n + 1);
}
void addEdge(int from, int to, int cap) {
return graph[from].push_back(Edge{to, cap, (int)graph[to].size()}),
graph[to].push_back(Edge{from, 0, (int)graph[from].size() - 1});
Expand Down Expand Up @@ -98,7 +100,9 @@ class DinicWithCost {
}
public:
void resize(int _n) { return graph.resize((n = _n) + 1), cur.resize(n + 1), dist.resize(n + 1), vis.resize(n + 1); }
void resize(int _n) {
return graph.resize((n = _n) + 1), cur.resize(n + 1), dist.resize(n + 1), vis.resize(n + 1);
}
void addEdge(int from, int to, int cap, int cost) {
return graph[from].push_back(Edge{to, cap, cost, (int)graph[to].size()}),
graph[to].push_back(Edge{from, 0, -cost, (int)graph[from].size() - 1});
Expand Down

0 comments on commit e514a8a

Please sign in to comment.