HDU-ACM 2024 Day2
T1004 a*b problem(HDU 7448)
不会。
T1005 小塔的养成游戏之梦(HDU 7449)
不会。
T1009 强攻计策(HDU 7453)
容易发现初始速度是多少对答案没有影响,所以我们默认初始速度为 \(0\)。题意相当于在平面直角坐标系上(横轴为时间,纵轴为速度),有一个目标高度,维护一条尽量接近目标的直线,但斜率只能是 \(-1/0/1\),要支持一段区间目标 \(+1\),求直线下方面积。
将一次区间 \(+1\) 拆成一段后缀 \(+1\) 和一段后缀 \(-1\)。注意到一次后缀 \(+1/-1\) 时至多只有一个位置发生向上/向下翻折,在这个位置前与目标的相对高度 \(-1/+1\),之后相对高度不变,那么此时面积的变化量容易用这个位置表示,我们现在的任务就是快速找到这个位置。
具体而言,设 \(h_i\) 表示直线在 \(x = i\) 处的相对高度,手玩容易发现当区间 \(+1\) 时,我们要找第一个 \(0/-1\),区间 \(-1\) 时,我们要找第一个 \(0/1\)。
现在我们要维护一个数据结构,支持区间 \(+1/-1\),区间找第一个 \(-1/0/1\),考虑分块,块内维护排序数组,修改时整块打标记,散块归并重构,询问时散块暴力,整块二分即可,平衡块长,时间复杂度 \(O(n \sqrt {n \log n})\),常数较小。
Code
#include <iostream>
#include <cmath>
#include <numeric>
#include <algorithm>
#include <vector>
using namespace std;
using LL = long long;
const int N = 1e5 + 5;
const int Mod = 1e9 + 7, Inv = (Mod + 1) / 2;
int n, m;
LL ans;
namespace Block {
int len, cnt;
int a[N], b[N], tag[N], bl[N], L[N], R[N];
void build () {
len = sqrt(n) * 0.4;
for (int i = 0; i <= n; ++i) {
bl[i] = i / len + 1;
}
cnt = bl[n];
R[0] = -1;
for (int i = 1; i <= cnt; ++i) {
L[i] = R[i - 1] + 1;
R[i] = min(n, L[i] + len - 1);
}
fill(a, a + n + 1, 0);
iota(b, b + n + 1, 0);
fill(tag, tag + cnt + 1, 0);
}
int first_val (int x, int y) {
for (int i = x; i <= R[bl[x]]; ++i) {
if (a[i] == y - tag[bl[x]]) {
return i;
}
}
for (int i = bl[x] + 1; i <= cnt; ++i) {
if (a[b[R[i]]] < y - tag[i] || a[b[L[i]]] > y - tag[i]) continue;
auto cmp = [&](int i, int j) -> bool {
return a[i] < j;
};
auto it = lower_bound(b + L[i], b + R[i] + 1, y - tag[i], cmp);
if (it != b + R[i] + 1 && a[*it] == y - tag[i]) return *it;
}
return n + 1;
}
int tmpa[N][2];
int al[2];
void add (int l, int r, int x) {
r = min(r, n);
auto rebuild = [&](int l, int r, int gl, int gr) -> void {
al[0] = 0, al[1] = 0;
for (int i = l; i <= r; ++i) {
int o = b[i] >= gl && b[i] <= gr;
tmpa[++al[o]][o] = b[i];
}
int p = l;
auto cmp = [&](int i, int j) -> bool {
return a[i] < a[j] || a[i] == a[j] && i < j;
};
for (int cur[2] = {1, 1}; cur[0] != al[0] + 1 || cur[1] != al[1] + 1; ) {
if (cur[0] != al[0] + 1 && (cur[1] == al[1] + 1 || cmp(tmpa[cur[0]][0], tmpa[cur[1]][1]))) {
b[p++] = tmpa[cur[0]][0], ++cur[0];
}
else {
b[p++] = tmpa[cur[1]][1], ++cur[1];
}
}
};
if (bl[l] == bl[r]) {
for (int i = l; i <= r; ++i) {
a[i] += x;
}
rebuild(L[bl[l]], R[bl[l]], l, r);
}
else {
for (int i = l; i <= R[bl[l]]; ++i) {
a[i] += x;
}
for (int i = L[bl[r]]; i <= r; ++i) {
a[i] += x;
}
rebuild(L[bl[l]], R[bl[l]], l, R[bl[l]]);
rebuild(L[bl[r]], R[bl[r]], L[bl[r]], r);
for (int i = bl[l] + 1; i <= bl[r] - 1; ++i) {
tag[i] += x;
}
}
}
}
void suf_add (int x) {
int pos = min(Block::first_val(x, 0), Block::first_val(x, 1));
ans += max(0, (n - pos) * 2 - 1);
Block::add(x, pos, -1);
}
void suf_minus (int x) {
int pos = min(Block::first_val(x, 0), Block::first_val(x, -1));
ans -= max(0, (n - pos) * 2 - 1);
Block::add(x, pos, 1);
}
int main () {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int T;
cin >> T;
while (T--) {
cin >> n >> m;
Block::build(), ans = 0;
for (int i = 1, l, r; i <= m; ++i) {
cin >> l >> r;
suf_add(l), suf_minus(r);
cout << ans % Mod * Inv % Mod << '\n';
}
}
return 0;
}
T1012 图计算(HDU 7456)
考虑对于每一张图分别维护并查集,我们使用启发式合并,这样可以保证每个结点的 \(fa\) 就是它的最高级祖先,对于每一个结点,为它在所有图中的 \(fa\) 序列哈希即可。
Code
#include <iostream>
#include <vector>
#include <tuple>
#include <unordered_map>
using namespace std;
using LL = long long;
using Tp = tuple<int, int, int>;
const int N = 5e4 + 5, M = 105;
int n, m, d, q;
struct Hash_Arr {
int len;
struct Hash {
int mod, base, len;
int pw[M], now;
void init (int mod_, int base_, int len_) {
mod = mod_, base = base_, now = 0, len = len_;
pw[0] = 1;
for (int i = 1; i <= len; ++i) {
pw[i] = 1ll * pw[i - 1] * base % mod;
}
}
void add (int x, int y) { now = (now + 1ll * (mod + y) * pw[x]) % mod; }
} ha[3];
void init (int len_) {
len = len_;
ha[0].init(1000000007, 1000000009, len);
ha[1].init(1000000021, 1000000033, len);
ha[2].init(1000000087, 1000000093, len);
}
void add (int x, int y) {
ha[0].add(x, y);
ha[1].add(x, y);
ha[2].add(x, y);
}
Tp get_val () { return make_tuple(ha[0].now, ha[1].now, ha[2].now); }
} h[N];
struct tHash {
const int tB = 998244353, tP = tB * tB;
int operator() (Tp x) const {
return get<0>(x) + get<1>(x) * tB * get<2>(x) * tP;
}
};
unordered_map<Tp, int, tHash> p;
LL ans;
void add (Tp x) {
int v = p[x]++;
ans += v;
}
void remove (Tp x) {
int v = --p[x];
ans -= v;
}
struct U {
int fa[N], id;
vector<int> vec[N];
void init (int id_) {
id = id_;
fill(vec + 1, vec + n + 1, vector<int>());
for (int i = 1; i <= n; ++i) {
vec[i].push_back(i);
fa[i] = i;
h[i].add(id, i);
}
}
void unite (int x, int y) {
x = fa[x], y = fa[y];
if (x == y) return;
if (vec[x].size() < vec[y].size()) swap(x, y);
for (auto v : vec[y]) {
vec[x].push_back(v);
remove(h[v].get_val());
h[v].add(id, x - fa[v]);
add(h[v].get_val());
fa[v] = x;
}
vec[y].clear();
}
} uf[M];
int main () {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int T;
cin >> T;
while (T--) {
cin >> n >> m >> d >> q;
for (int i = 1; i <= n; ++i) {
h[i].init(d + 1);
}
for (int i = 1; i <= d + 1; ++i) {
uf[i].init(i);
}
p.clear(), ans = 0;
for (int i = 1; i <= n; ++i) {
add(h[i].get_val());
}
for (int i = 1, u, v; i <= m; ++i) {
cin >> u >> v;
for (int j = 1; j <= d + 1; ++j) {
uf[j].unite(u, v);
}
}
for (int i = 1, u, v, w; i <= q; ++i) {
cin >> u >> v >> w;
uf[w].unite(u, v);
cout << ans << '\n';
}
}
return 0;
}
HDU-ACM 2024 Day2的更多相关文章
- hdu acm 1028 数字拆分Ignatius and the Princess III
Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- HDU ACM 题目分类
模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...
- hdu acm 1166 敌兵布阵 (线段树)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- hdu acm 2082 找单词
找单词 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- HDU ACM 1325 / POJ 1308 Is It A Tree?
Is It A Tree? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- HDU ACM 1134 Game of Connections / 1130 How Many Trees?(卡特兰数)
[题目链接]http://acm.hdu.edu.cn/showproblem.php?pid=1134 [解题背景]这题不会做,自己推公式推了一段时间,将n=3和n=4的情况列出来了,只发现第n项与 ...
- HDU ACM Eight
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 解题背景: 看到八数码问题,没有任何的想法,偶然在翻看以前做的题的时候发现解决过类似的一道题,不 ...
- HDU ACM 1690 Bus System (SPFA)
Bus System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU ACM 1224 Free DIY Tour (SPFA)
Free DIY Tour Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- HDU ACM 1869 六度分离(Floyd)
六度分离 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
随机推荐
- 【Vue】13 VueRouter Part3 路由守卫
单页应用中,只存在一个HTML文件,网页的标签,是通过title标签显示的,我们在单页应用中如何修改? JS操作: window.document.title = "标签名称" 也 ...
- agnostic在计算机领域的常用翻译 —— location-agnostic deployment option
关于agnostic的翻译: 例子: NVIDIA OSMO scales workloads across distributed environments. For robotics worklo ...
- 服务器上运行 xvbf 时报错 —— Unknown encoder 'libx264'
解决方法: 使用conda环境(不具体交代) conda install ffmpeg 成功运行:
- 大连人工智能计算平台——华为昇腾AI平台——高性能计算HPC——如何在MPI中支持multiprocessing和fork操作——如何在HPC平台上使用pytorch——是否可以通过调度器的提交参数绕过HPC的计费系统
本文要讨论的就是如何在MPI中支持multiprocessing和fork操作,但是这个问题同时也是如何在HPC平台如何使用pytorch的问题,可以说这两个问题其实是同一个问题,而这个问题的解决过程 ...
- 代码随想录Day16
513.找树左下角的值 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值. 假设二叉树中至少有一个节点. 示例 1: 输入: root = [2,1,3] 输出: 1 示 ...
- redis集群之哨兵模式
redis集群之哨兵模式 1.集群部署 安装配置可参考一下地址: https://www.cnblogs.com/zhoujinyi/p/5569462.html 2.与springboot集成 这里 ...
- git push --recurse-submodules = on-demand 递归push
I have the following project structure: root-project | |-- A | | | |-- C | |-- B A和B是根项目的子模块. C又是项目A ...
- 国内IT行业67家外包公司,有多少程序员在里面待过?
之前写过一篇关于外包公司的文章, <什么是软件外包公司?要不要去外包公司?> 很多粉丝看了后,感觉都在说自己, 存在即合理, 外包大幅度降(可)低(以)了(压)用(榨)人(更)成(多)本( ...
- 基于docker搭建单机测试ELK
说明:本次使用的windows系统,利用vm进行安装虚拟机,安装的只是单测试单机版elk. 一.下载vm 自行官网下载 二.安装centos7系统 自己有现成的镜像跳过,没有自行查找资料完成 三.进行 ...
- python的命名风格(下划线篇)
一个下划线开头的代表模块私有 用from xxx import * 时python会自动屏蔽带下划线的东西,想要取消屏蔽可以用__all__方法,但不建议(不符合规范) 两个下划线开头的代表类私有