当前位置: 首页 > news >正文

2025杭电多校(2)

F

https://acm.hdu.edu.cn/showproblem.php?pid=7996

题意

有两场比赛,统计对于每个 \(i\) ,有多少个人排在 \(i\) 的前面,需要去重。

思路

第一思路是统计每个位置 \(i\) 前面有多少人数,发现有个小容斥在这里,两场比赛排名前的总人数减去两场都在排名前的人数。

用树状数组统计第二场比赛在排名前的人数,也就是同时排在前面的人数。

代码

#include<bits/stdc++.h>
using namespace std;using ll = long long;void solve(){int n;cin >> n;vector<int> a(n + 1);vector<int> pos(n + 1);for(int i = 1; i <= n; i++){cin >> a[i];}for(int i = 1; i <= n; i++){int x;cin >> x;pos[x] = i;}vector<int> c(n + 5);auto lowbit = [&](int x){return x & -x;};auto add = [&](int k, int x){while(k <= n){c[k] += x;k += lowbit(k);}};auto find = [&](int k){int res = 0;while(k != 0){res += c[k];k -= lowbit(k);}return res;};vector<int> ans(n + 1);for(int i = 1; i <= n; i++){ans[a[i]] = i - 1 + pos[a[i]] - 1;ans[a[i]] -= find(pos[a[i]]);add(pos[a[i]], 1);}for(int i = 1; i <= n; i++){cout << ans[i] << " ";}
}int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);ll t;cin >> t;while(t--)solve();
}

H

https://acm.hdu.edu.cn/showproblem.php?pid=7998

思路

先检查对角线,翻出 \(1\) 的概率为 \(1/n(1 + 2 + ... + n) = (n + 1)/2\), 翻出后花费两次确定方向,即 \((1 + 2)/2\),最后有 \(n - 2\) 次填充,共 \(3n/2\).

代码就不贴了,输出记得一定只能输出四位小数。

I

https://acm.hdu.edu.cn/showproblem.php?pid=7999

思路

题目求一颗树上 \(u\)\(v\) 路径上的最大值,并且要支持修改,那么自然想到重链剖分再加上线段树修改,查询。

但这里的修改并不是修改该点,而是该点周围的点,考虑到重链剖分的查询,我们发现链上的部分是已经在线段树上处理好的,修改需要 \(O(log\;n)\) 的时间复杂度。

而链头的部分可以单独的处理其新的增加,这里多开一个数组,记录链头的父亲有多少额外的增加,在查询时 \(O(1)\) 的时间复杂度就可以处理这个点。

代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long;const int N = 1e5 + 5;
struct node{int sum;int ma;node operator+(const node& b){node res;res.sum = sum + b.sum;res.ma = max(ma, b.ma);return res;}};node s[N<<2];void push_up(int n){s[n] = s[n<<1] + s[n<<1|1];
}void update(int ql, int qr, int x, int l, int r, int n){if(l == r && ql == l){s[n].sum = x;s[n].ma = x;return ;}int mid = (l + r) / 2;if(ql <= mid)update(ql, qr, x, l, mid, n<<1);if(qr > mid)update(ql, qr, x, mid+1, r, n<<1|1);push_up(n);
}node query(int ql, int qr, int l, int r, int n){if(ql <= l && r <= qr){return s[n];}int mid = (l + r) / 2;node res;res.ma = -1e9;res.sum = 0;if(ql <= mid)res = res + query(ql, qr, l, mid, n<<1);if(qr >  mid)res = res + query(ql, qr, mid+1, r, n<<1|1);return res;
}void solve(){int n, m;cin >> n >> m;vector<int> a(n + 1);vector<int> f(n + 1);vector<int> dfn(n + 1);vector<int> top(n + 1);vector<int> big(n + 1);vector<int> r(n + 1);vector<int> dep(n + 1);vector<int> sz(n + 1);vector<int> ad(n + 1);int idx = 0;vector<vector<int>> e(n + 1);for(int i = 1; i <= n; i++){cin >> a[i];}for(int i = 1; i < n; i++){int x, y;cin >> x >> y;e[x].push_back(y);e[y].push_back(x);}auto dfs1 = [&](auto&& dfs1, int u, int fa) -> void {sz[u] = 1;for(auto v : e[u]){if(v == f[u])continue;f[v] = u;dep[v] = dep[u] + 1;dfs1(dfs1, v, u);sz[u] += sz[v];if(sz[big[u]] < sz[v])big[u] = v;}};auto dfs2 = [&](auto&& dfs2, int u, int tp) -> void {dfn[u] = ++idx;r[idx] = u;top[u] = tp;if(big[u] != 0)dfs2(dfs2, big[u], tp);for(auto v : e[u]){if(v == big[u] || v == f[u])continue;dfs2(dfs2, v, v);}};f[1] = 0;dep[1] = 1;dfs1(dfs1, 1, 0);dfs2(dfs2, 1, 1);auto pre_query = [&](int u, int v) {node res;res.sum = 0;res.ma = -1e9;while(top[u] != top[v]){if(dep[top[u]] < dep[top[v]])swap(u, v);res = res + query(dfn[top[u]], dfn[u], 1, n, 1);res.ma = max(res.ma, query(dfn[top[u]], dfn[top[u]], 1, n, 1).ma + ad[f[top[u]]]);u = f[top[u]];}if(dfn[u] > dfn[v])swap(u, v);res = res + query(dfn[u], dfn[v], 1, n, 1);if(u == top[u]){res.ma = max(res.ma, query(dfn[u], dfn[u], 1, n, 1).ma + ad[f[u]]);}return res;};for(int i = 1; i <= n; i++){update(dfn[i], dfn[i], a[i], 1, n, 1);}for(int i = 1; i <= m; i++){int op;cin >> op;if(op == 1){int x, y;cin >> x >> y;cout << pre_query(x, y).ma << "\n";}else{int x, y;cin >> x >> y; ad[x] += y;if(f[x] != 0){int num = pre_query(f[x], f[x]).sum;update(dfn[f[x]], dfn[f[x]], y + num, 1, n, 1);}if(big[x] != 0){int num = pre_query(big[x], big[x]).sum;update(dfn[big[x]], dfn[big[x]], y + num, 1, n, 1);}}}
}int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;cin >> t;while(t--)solve();return 0;
}

K

https://acm.hdu.edu.cn/showproblem.php?pid=8001

思路

对题意解读之后发现我们对于给定的 \(l\)\(r\) 区间,我们把 \(1\) 中间的 \(0\) 的个数记作一个数列,那么答案就是从最右边向左求一个尽可能长的一个公差为 \(1\) 的等差数列。

让找到的数列从右到左呈现 \(l_1,\;l_2,\;...,\;l_i\), 答案为 \(2 * (i - 1) + l_i\) .

最后我们用线段树维护等差数列即可。

代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long;const int N = 5.1e5 + 10;
struct node{int l0, r0, len, cnt, over, st, ed;node(){};node(int x){len = 1;over = 0;st = ed = -1;if(x == 1){l0 = r0 = 0;cnt = 1;}else {l0 = r0 = 1;cnt = 0;}}
};node s[N << 2];int a[N];node merge(node l, node r){node ans;ans.l0 = l.l0;if(l.l0 == l.len)ans.l0 += r.l0;ans.r0 = r.r0;if(r.r0 == r.len)ans.r0 += l.r0;ans.len = l.len + r.len;ans.cnt = l.cnt + r.cnt;if(ans.cnt <= 1){ans.over = 0;ans.st = -1;ans.ed = -1;return ans;}if(r.over || l.cnt == 0){ans.over = r.over;ans.st = r.st;ans.ed = r.ed;return ans;}if(r.cnt == 0){ans.over = l.over;ans.st = l.st;ans.ed = l.ed;return ans;}int lnk = l.r0 + r.l0;if(l.cnt !=  1 && r.cnt != 1){if(l.ed == lnk + 1 && r.st == lnk - 1){ans.st = l.st;ans.ed = r.ed;ans.over = l.over;}else if(r.st == lnk - 1){ans.over = 1;ans.st = lnk;ans.ed = r.ed;}else {ans.over = 1;ans.st = r.st;ans.ed = r.ed;}return ans;}if(l.cnt == 1 && r.cnt == 1){ans.over = 0;ans.st = ans.ed = lnk;return ans;}if(l.cnt == 1){if(lnk == r.st + 1){ans.over = 0;ans.st = lnk;ans.ed = r.ed;}else {ans.over = 1;ans.st = r.st;ans.ed = r.ed;}return ans;}if(r.cnt == 1){if(lnk + 1 == l.ed ){ans.over = 0;ans.ed = lnk;ans.st = l.st;}else {ans.over = 1;ans.ed = lnk;ans.st = lnk;}return ans;}return ans;
}void push_up(int n){s[n] = merge(s[n<<1], s[n<<1|1]);
}void build(int l, int r, int n){if(l == r){s[n] = node(a[l]);return ;}int mid = (l + r) / 2;build(l, mid, n<<1);build(mid+1, r, n<<1|1);push_up(n);
}void update(int pos, int l, int r, int n){if(l == r && l == pos){s[n].l0 ^= 1;s[n].r0 ^= 1;s[n].cnt ^= 1;return ;}int mid = (l + r) / 2;if(pos <= mid)update(pos, l, mid, n<<1);else update(pos, mid+1, r, n<<1|1);push_up(n);
}node query(int ql, int qr, int l, int r, int n){if(ql <= l && r <= qr){return s[n];}int mid = (l + r) / 2;if(qr <= mid)return query(ql, qr, l, mid, n<<1);if(ql > mid)return query(ql, qr, mid+1, r, n<<1|1);return merge(query(ql, qr, l, mid, n<<1), query(ql, qr, mid+1, r, n<<1|1));
}void solve(){int n, m;cin >> n >> m;for(int i = 1; i <= n; i++){char c;cin >> c;a[i] = c - '0';}build(1, n, 1);for(int i = 1; i <= m; i++){int op;cin >> op;if(op == 1){int l, r;cin >> l >> r;node num = query(l, r, 1, n, 1);if(num.cnt == 0){cout << "0\n";}else if(num.cnt == 1 || num.ed != num.r0 + 1){cout << num.r0 << "\n";}else {cout << num.st + 2 * (num.st - num.ed + 1) << "\n";}}else {int x;cin >> x;update(x, 1, n, 1);}}
}int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;cin >> t;while(t--)solve();return 0;
}

L

https://acm.hdu.edu.cn/showproblem.php?pid=8002

题意

给定 \(n\) 个非负整数 \(a_i\),不选相邻的数,使得选取的所有数的异或和最大。 ( \(n <= 50\), 内存限制 \(3MB\) )

思路

答案需要统计的异或和最大,想到线性基,然后模拟所有可能的选取情况,选取 \(i\) 之后 考虑选取 \(i + 2\)\(i + 3\), 同时由于线性基的性质,在中间本来不选的情况下,选取中间值是不会变劣的。

代码

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;void solve(){vector<ll> p(61);auto insert = [&](vector<ll>& p, ull x){for(int i = 60; ~i; --i){if(!(x >> i))continue;if(!p[i]){p[i] = x;break;}x ^= p[i];}};int n;cin >> n;vector<ll> a(n + 1);for(int i = 1; i <= n; i++){cin >> a[i];}ll ans = 0;auto dfs = [&](auto&& dfs, vector<ll> p, int id) -> void {if(id > n){ll temp = 0;for(int i = 60; ~i; --i){if((p[i] ^ temp) > temp){temp ^= p[i]; }}ans = max(ans, temp);return ;}insert(p, a[id]);dfs(dfs, p, id + 2);dfs(dfs, p, id + 3);};dfs(dfs, p, 1);// er();dfs(dfs, p, 2);cout << ans << "\n";}int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;cin >> t;while(t--)solve();return 0;
}
http://www.wxhsa.cn/company.asp?id=4441

相关文章:

  • latex 打印生僻字
  • CSP-S 2025 游记(The Last CSP ver.)
  • 电机ADC采集
  • 道德经
  • TokenFlow: Unified Image Tokenizer for Multimodal Understanding and Generation - jack
  • digitalworld.local: TORMENT - 实践
  • 8.25-9.2周报六
  • Go by Example(3.Variables)
  • 小程序分包方法
  • 9.3-9.10周报七
  • pyinstaller打包整个文件文件夹和相关exe,三方库
  • Web前端入门第 87 问:JavaScript 中 setInterval 和 setTimeout 细节
  • 基于Python+Vue开发的农产品商城管理系统源码+运行
  • 多人多次并发
  • B. Alternating Current
  • 虚拟电厂运行机制
  • Reinforcing Image Generation with Collaborative Semantic-level and Token-level CoT - jack
  • 创建我第一个带记忆能力的langchain机器人
  • GitHub超 30000+ star , 超强大的开源项目Supervision
  • 深入解析:【JavaEE】网络原理初识
  • Office文档投毒技术:SHVE中的会话劫持视觉利用新突破
  • 爬虫逆向--Day22Day23--核心实战案例【荔枝网】【WASM学习】
  • 简洁美观!一款值得 Star 的 Java 博客项目!
  • 数据结构与算法-33.图-加权有向图最短路径
  • 白子的情人节礼物
  • 白子的情人节礼物 题解
  • Ubuntu上进行Zookeeper集群部署
  • The Landscape of Agentic Reinforcement Learning综述 - jack
  • A Survey of Reinforcement Learning for Large Reasoning Models - jack
  • r-nacos支持mcp,内置mcp server支持让注册到r-nacos的普通http接口通过r-nacos直接转化成mcp服务对外提供服务。