首页 > 其他分享 >APIO 2024

APIO 2024

时间:2024-05-28 10:59:43浏览次数:23  
标签:rt cnt return int 2024 ++ APIO id

A-September

模拟题。

取出 \(m\) 个人里包含相同元素的段,再判断删掉的是不是都是叶子就好,时间复杂度 \(O(nm)\)

#include <bits/stdc++.h>

using namespace std;

int solve(int n, int m, vector<int> fa, vector<vector<int>> s) {
	int ans = 0, cnt = 0;
	vector<int> d(n), c(n), del(n);
	auto upd = [&](int j) -> void {
		for (int i = 0; i < m; i++) {
			if (!c[s[i][j]]) cnt++;
			if (++c[s[i][j]] == m) {
				del[s[i][j]] = 1;
				for (int u = s[i][j]; !d[u] && del[u]; d[u = fa[u]]--) cnt--;
			}
		}
	};

	for (int i = 1; i < n; i++) d[fa[i]]++;
	for (int l = 0, r; l < n - 1; ans++, l = r + 1) for (upd(r = l); cnt; upd(++r));
	return ans;
}

B-Train

DP。

考虑把边看做点,把点看做边,按边的 \(A_i\) 从小到大遍历:

记 \(f_i\) 为到第 \(i\) 条边的起点的最小花费。

\[f_i = \min_{Y_j = X_i, B_j \le A_i} \{f_j + T_{X_i} \times cnt_{B_j + 1, A_i - 1} \} + C_i \]

其中 \(cnt_{l, r}\) 表示在满足 \([L_i, R_i] \sube [l, r]\) 的餐 \(i\) 的个数,可以用主席树快速计算。

时间复杂度 \(\mathcal O(m^2 \log w)\)。

还不够,继续优化:

考虑在每个终点建一个单调队列,这样转移就是 \(\mathcal O(m \log w)\) 的了,难点在插入每顿餐的时候维护好这些单调队列。

因为在同一个星球上吃一顿饭的费用是确定的,所以对于每一个单调队列里的每一个 \(f_j + T_{X_i} \times cnt_{B_j + 1, A_i - 1}\),我们可以算出来它什么时候会把它前面的元素 \(f_k + T_{X_i} \times cnt_{B_k + 1, A_i - 1}\) 爆掉,即在该星球上吃的饭中 \(l_i \in [B_j + 1, B_k]\) 的个数等于 \(\left\lceil \dfrac{f(k) - f(j)}{T_{X_i}} \right\rceil\) 时。

然后我们标记这顿饭,并在将它考虑进来的时候把 \(k\) 删掉,因为随着 \(A_i\) 变大,\(cnt_{B_k + 1, A_i - 1} - cnt_{B_j + 1, A_i - 1}\) 不降,故此时 \(j\) 比 \(k\) 更优,未来一定 \(j\) 比 \(k\) 更优。

标记需要支持查询第 \(k\) 大,在前面的主席树上就能解决。

时间复杂度 \(\mathcal O((m + w)\log w)\)。

#include <bits/stdc++.h>
#include "train.h"

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vint;

constexpr int N = 1e5 + 10, TN = N * 40, INF = 1e9;

int n, m, w, tot, rt[TN], id[N], hd[N], tl[N];
ll f[N];
bool vis[N];

struct Train {
	int x, y, a, b, c;
	bool operator<(const Train &rhs) const {return a < rhs.a;}
} tr[N];

struct Meal {int l, r, rk;} ml[N], mr[N];
bool cmpl(const Meal &lhs, const Meal &rhs) {return lhs.l != rhs.l ? lhs.l < rhs.l : lhs.r < rhs.r;}
bool cmpr(const Meal &lhs, const Meal &rhs) {return lhs.r != rhs.r ? lhs.r < rhs.r : lhs.l < rhs.l;}

vint c[N], to[N], pre[N];

priority_queue<pii, vector<pii>, greater<pii>> q;

namespace PST {
	int tot;
	struct Seg {int w, ls, rs;} t[TN];

	inline int newt(int rt) {t[++tot] = t[rt]; return tot;}
	
	void upd(int rt0, int &rt, int l, int r, int x) {
		rt = newt(rt0), t[rt].w++;
		if (l == r) return;
		int mid = (l + r) >> 1;
		x <= mid ? upd(t[rt0].ls, t[rt].ls, l, mid, x) : upd(t[rt0].rs, t[rt].rs, mid + 1, r, x);
	}

	int query(int pos, int l, int r, int x, int y) {
		if (x <= l && r <= y) return t[pos].w;
		int mid = (l + r) >> 1, res = 0;
		if (x <= mid) res = query(t[pos].ls, l, mid, x, y);
		if (y > mid) res += query(t[pos].rs, mid + 1, r, x, y);
		return res;
	}

	int kth(int rx, int ry, int l, int r, int k) {
		if (l == r) return l;
		int mid = (l + r) >> 1, lsz = t[t[ry].ls].w - t[t[rx].ls].w;
		if (k <= lsz) return kth(t[rx].ls, t[ry].ls, l, mid, k);
		return kth(t[rx].rs, t[ry].rs, mid + 1, r, k - lsz);
	}
}

ll solve(int n, int m, int w, vint T, vint X, vint Y, vint A, vint B, vint C, vint L, vint R) {
	for (int i = 0; i < m; i++) tr[i] = {X[i], Y[i], A[i], B[i], C[i]};
	for (int i = 0; i < w; i++) mr[i] = {L[i], R[i]};
	sort(mr, mr + w, cmpr);
	for (int i = 0; i < w; i++) mr[i].rk = i, ml[i] = mr[i];
	sort(ml, ml + w, cmpl);
	for (int i = 0; i < w; i++) {
		if (i) rt[i] = rt[i - 1];
		PST::upd(rt[i], rt[i], 0, w - 1, ml[i].rk);
	}
	sort(tr, tr + m);
	memset(f, -1, sizeof(f)), memset(tl, -1, sizeof(tl));
	to[0].emplace_back(m), pre[0].emplace_back(-1), f[m] = 0, tr[m].y = 0, tr[m].b = -1, hd[0] = tl[0] = 0;

	int cnt = 0;

	auto val = [&](int i) -> ll {
		if (cnt) {
			int p = upper_bound(ml, ml + w, Meal{tr[i].b, INF, INF}, cmpl) - ml;
			return f[i] + 1ll * (cnt - (p ? PST::query(rt[p - 1], 0, w - 1, 0, cnt - 1) : 0)) * T[tr[i].y];
		}
		return f[i];
	};

	auto kth = [&](int l, int r, int k) -> int {
		int x = lower_bound(ml, ml + w, Meal{l, -1, -1}, cmpl) - ml, y = upper_bound(ml, ml + w, Meal{r, INF, INF}, cmpl) - ml;
		if (!y || y - x < k) return -1;
		return PST::kth(x ? rt[x - 1] : 0, rt[y - 1], 0, w - 1, k);
	};

	auto calc = [&](int i) -> void {
		int p = tr[i].y, j = to[p][pre[p][id[i]]], rk = kth(tr[j].b + 1, tr[i].b, (f[i] - f[j] + T[p] - 1) / T[p]);
		if (rk != -1) c[rk].emplace_back(i);
	};

	for (int i = 0; i < m; i++) {
		while (cnt < w && mr[cnt].r < tr[i].a) {
			int cur = cnt++;
			for (int x : c[cur]) if (!vis[x]) {
				int p = tr[x].y;
				if (id[x] == hd[p]) continue;
				while (val(to[p][pre[p][id[x]]]) >= val(x)) {
					vis[to[p][pre[p][id[x]]]] = 1;
					if (pre[p][id[x]] == hd[p]) {hd[p] = id[x]; break;}
					pre[p][id[x]] = pre[p][pre[p][id[x]]];
				}
				if (hd[p] != id[x]) calc(x);
			}
		}
		while (!q.empty() && q.top().first <= tr[i].a) {
			int x = q.top().second; q.pop();
			int p = tr[x].y;
			while (hd[p] <= tl[p] && val(x) <= val(to[p][tl[p]])) {
				if (hd[p] == tl[p]) {hd[p] = to[p].size(); break;}
				vis[to[p][tl[p]]] = 1, tl[p] = pre[p][tl[p]];
			}
			id[x] = to[p].size(); to[p].emplace_back(x);
			if (hd[p] > tl[p]) pre[p].emplace_back(-1), hd[p] = tl[p] = id[x];
			else pre[p].emplace_back(tl[p]), tl[p] = id[x], calc(x);
		}
		int p = tr[i].x;
		if (hd[p] <= tl[p]) f[i] = val(to[p][hd[p]]) + tr[i].c, q.emplace(tr[i].b, i);
	}
	cnt = w; ll ans = 9e18;
	for (int i = 0; i < m; i++) if (tr[i].y == n - 1 && f[i] != -1) ans = min(ans, val(i));
 	return ans < 9e18 ? ans : -1;
}

C-show

乱搞。

树的规模肯定越大越好,所以取 \(n = 5000\)。

对每一个点 \(i \ge 2\),连边 \(i \to X \bmod (i - 1) + 1\)。得到 \(2499\) 个同余方程,可以解出 \(X\)。

也不用 exCRT,朴素 \(\mathcal O(n^2)\) 解就行。

Alice:

#include <bits/stdc++.h>
#include "Alice.h"

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;

constexpr int N = 5e3;

vector<pii> Alice() {
    vector<pii> res;
    ll x = setN(N);
    for (int i = 2; i <= N; i++) res.emplace_back(pii(i, x % (i - 1) + 1));
    return res;
}

Bob:

#include <bits/stdc++.h>
#include "Bob.h"

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef __int128 lll;

ll Bob(vector<pii> v) {
    lll x = 0, p = 1;
    for (auto e : v) {
        int xi = e.first - 1, pi = e.second - 1;
        while (x % pi != xi) x += p;
        p = p * pi / __gcd(p, lll(pi));
        if (p > 1e18) return x;
    }
    return x;
}

标签:rt,cnt,return,int,2024,++,APIO,id
From: https://www.cnblogs.com/chy12321/p/18217393

相关文章

  • 视觉语音识别挑战赛 CNVSRC 2024
        CNVSRC2024由NCMMSC2024组委会发起,清华大学、北京邮电大学、海天瑞声、语音之家共同主办。竞赛的目标是通过口唇动作来推断发音内容,进一步推动视觉语音识别技术的发展。视觉语音识别(也称为读唇技术)是一种通过观察唇部动作推断发音内容的技术,广泛应用于公共安全、......
  • CISCN 2024 reverse 国赛复盘
    asm_re手撕汇编,配合GPT分析,加上一点点的猜测。在汇编推出可以看到加密逻辑:value=ord(f[1])value*=0x50;value+=0x14;value^=0x4D;value+=0x1E;print(value)已经知道第一个为f,f经过加密得到0x1FD7,l可以得到0x21B7。同理,根据数据段可以还原出flag,......
  • 【2024-05-27】高中校友会
    20:00三十岁之前,能搞清楚自己想要什么就不错了。黎明前的黑暗是最难熬的,你到那块儿难,别人也难,谁多坚持一秒,谁就是胜利者。                                ——林宝军周六参加了高中的广州校友会活动。在......
  • 【2024-05-26】连岳摘抄
    23:59我现在终于明白教养孩子绝不仅仅只是修正他的缺点,同时还要发掘他的优势与美德,帮助孩子在社会.上找到一一个安身立命之所,使他的积极人格特质得以全面发展。                                ——马丁·塞......
  • 2024年西安交通大学程序设计校赛
    2024年西安交通大学程序设计校赛因为本人比较菜,所以只补赛时(校内训练赛)写了但没写出的题,完整题解可以参考洛谷的巨巨~:https://www.luogu.com.cn/article/vzlnmec8K.崩坏:星穹铁道关键题面:Corycle想成为星穹铁道高手,为此他需要对自己的配队了如指掌。由于角色有多种职业,同时......
  • 郑州大学2023-2024第二学期高级语言程序设计-实验6
    郑州大学2023-2024第二学期高级语言程序设计-实验61抗疫凯旋2求10个点到原点的距离和3最小公倍数4变量有多少字节?5是否是斐波那契家族的一员?6递归实现逆序输出整数7河南的抗疫英雄8出生年9汉诺塔问题10素因子分解1抗疫凯旋这道题已经给了提示如何在while......
  • 【专题】2024餐饮行业及营销趋势报告合集PDF分享(附原数据表)
    原文链接:https://tecdat.cn/?p=36256原文出处:拓端数据部落公众号2024年,餐饮行业的趋势展望聚焦于健康、国潮、单品爆款和情感体验四大方向。首先,健康成为了消费者在选择餐饮时的首要考量。人们越来越注重食材的新鲜度和健康性,对菜品的口味也有了更高的要求。这意味着餐饮品牌需......
  • 2024年5月27日第五十六篇
    今天做了一个网页开发,联系了自己的增删改查,和弹出式表单的设计。<template><el-containerclass="layout-container-demo"><el-asidewidth="200px"><el-scrollbar><el-menu:default-openeds="['1','3�......
  • 2024/05/27
    今日学习有关知识时长:78分钟代码行数:80行发表博客数量:1篇今日学习的内容主要是有关数据库操作中的触发器和储存过程。触发器(trigger)就相当于事件绑定,当你进行某类sql语句操作时将会自动调用你你所设置的触发器来进行操作。储存过程(procedure)就相当于我们Java中的方法,可以带有......
  • MindSponge分子动力学模拟——多路径分子模拟(2024.05)
    技术背景在前面的MindSponge教程系列博客中,我们已经介绍过MindSponge分子动力学模拟框架的基础功能使用方法,例如MindSponge的安装与使用、定义分子系统、计算单点能和迭代器等等。这些模块和功能,更多的是凭借MindSpore深度学习框架的自动微分、GPU加速和Python语言的灵活性,而本文......