Say 题选记(9.21 - 9.27)

news/2025/9/25 22:26:40/文章来源:https://www.cnblogs.com/Hengqwq/p/19112203

P2048 [NOI2010] 超级钢琴

如何求长度在 \([L,R]\) 的子串中,子串和前 \(k\) 大的那些。
首先显然可以转化为前缀和。考虑 \(k = 1\) 的情况,把以 \(i(1 \le i \le n)\) 为右端点,\(j \in [i - R + 1, i - L + 1]\) 为左端点中最大的字串再求一遍最大值即可。这个用 st 表可以做。然后 \(k > 1\) 的思路类似这题。都是开一个优先队列,每次取最大的,然后进行分裂,把新的可能的最大的推进去,进行 \(k\) 遍即可。

Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef tuple<int, int, int, int, int> tpi;
const int N = 500005;
int a[N], n, sum[N], st[N][20], k, L, R;
int get(int x, int y){return sum[x] < sum[y] ? x : y;
}
int query(int l, int r){if(l > r) return 1e9;int d = __lg(r - l + 1);return get(st[l][d], st[r - (1 << d) + 1][d]);
}
priority_queue<tpi> q;
int main(){cin.tie(nullptr)->sync_with_stdio(0);cin >> n >> k >> L >> R;for(int i = 1; i <= n; ++i) cin >> a[i], sum[i] = sum[i - 1] + a[i], st[i][0] = i;for(int j = 1; (1 << j) <= n; ++j){for(int i = 0; i + (1 << j) - 1 <= n; ++i){st[i][j] = get(st[i][j - 1], st[i + (1 << j - 1)][j - 1]);}}for(int i = L; i <= n; ++i){int l = i - R, r = i - L;l = max(l, 0);int pos = query(l, r);q.emplace(sum[i] - sum[pos], i, pos, l, r);}ll ans = 0;while(k){auto [val, i, t, _l, _r] = q.top();q.pop();ans += val;if(_l < t){int pos = query(_l, t - 1);q.emplace(sum[i] - sum[pos], i, pos, _l, t - 1);}if(t < _r){int pos = query(t + 1, _r);q.emplace(sum[i] - sum[pos], i, pos, t + 1, _r);}--k;}cout << ans;return 0;
}

P4436 [HNOI/AHOI2018] 游戏

首先可以先把没有锁的房间并在一起看。
部分分给了一些提示,当 \(y \le x\) 恒成立时,只有可能是左边房门开右边房门,并且如果左边的房间能开锁到底右边的房间,那么右边房间能到的左边房间也能到。因此考虑记忆化。左边更新时直接从右边能到的最远的看能不能打开门锁,复杂度就是线性了。
\(y > x\) 时也是同理,也可以记忆化。难处貌似是既有 \(y \le x\) 也有 \(y > x\) 时转移顺序不知道怎么搞。如果 \(y \le x\) 就连一条 \(x + 1 \to x\) 的边,表示得先更新 \(x + 1\) 再更新 \(x\),反过来同理,那么就可以用拓扑排序钦定转移顺序。
注意细节,如果左右都可以暴力扩展时,要同时向两边扩,因为有可能右边的钥匙在向左还没扩到的地方。

Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
int p, n, f[N], m, e[N][2], l[N], r[N], g[N][2], odeg[N], ideg[N];
int main(){cin.tie(nullptr)->sync_with_stdio(0);cin >> n >> m >> p;for(int i = 1; i <= n; ++i) l[i] = r[i] = f[i] = i;for(int i = 1; i <= m; ++i){int u, t;cin >> u >> t;e[u][1] = t, e[u + 1][0] = t;}for(int i = 1; i <= n - 1; ++i) if(!e[i][1]) f[i + 1] = l[i + 1] = l[i];for(int i = n; i >= 2; --i) if(!e[i][0]) r[i - 1] = r[i];for(int i = 1; i <= n; ++i){// cout << f[i] << ' ' << l[i] << ' ' << r[i] << '\n';if(!e[i][1]) continue;if(e[i][1] <= i) g[f[i + 1]][odeg[f[i + 1]]++] = f[i], ++ideg[f[i]];else g[f[i]][odeg[f[i]]++] = f[i + 1], ++ideg[f[i + 1]];}queue<int> q;for(int i = 1; i <= n; ++i){if(!ideg[i] && f[i] == i) q.push(i);}while(!q.empty()){int u = q.front(); q.pop();// cout << u << ":\n";int x = u, y = u;while(1){bool fl = 0;if(x < n && e[r[f[x]]][1] >= l[u] && e[r[f[x]]][1] <= r[u]) x = r[f[x]] + 1, r[u] = r[f[x]], fl = 1;if(y > 1 && e[l[f[y]]][0] <= r[u] && e[l[f[y]]][0] >= l[u]) y = l[f[y]] - 1, l[u] = l[f[y]], fl = 1; if(!fl) break;}for(int k = 0; k < odeg[u]; ++k){// cout << g[u][k] << '\n';--ideg[g[u][k]];if(!ideg[g[u][k]]) q.push(g[u][k]);}}while(p--){int x, y;cin >> x >> y;cout << (l[f[x]] <= y && r[f[x]] >= y ? "YES" : "NO") << '\n';}return 0;
}

P4517 [JSOI2018] 防御网络

给定一颗点仙人掌,求点集的所有子集的最小斯坦纳树权值之和。

点仙人掌的性质类似于基环树。还是考虑边的贡献。如果 \((u,v)\) 是一条树边,那么贡献是 \((2^{siz_u} - 1)(2^{siz_v} - 1)\)。环上的情况相对复杂。记 \(L\) 为环上被选择的点相邻的最大值(包括最后一个和第一个的距离),那么贡献为环长 \(c\) 减去 \(L\)。那么就可以考虑枚举 \(L\),和断环为链的地方,做一遍 dp,统计方案。限制就是相邻点距离。前缀和优化,可以做到 \(O(N^3)\)

Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e2 + 5, mod = 1e9 + 7;
vector<int> e[N], vcc[N];
int n, m, cnt, dfn[N], low[N], tsp, st[N], tp;
bitset<N> on;
ll pw[N], val[N], f[N][2], ans, sumf[N][2];
ll qpow(ll a, ll b){ll res = 1;for(;b; b >>= 1, (a *= a) %= mod){if(b & 1) (res *= a) %= mod;}return res;
}
void tarjan(int u){dfn[u] = low[u] = ++tsp;st[++tp] = u;for(int v : e[u]){if(!dfn[v]){tarjan(v);low[u] = min(low[u], low[v]);if(low[v] == dfn[u]){++cnt;// cout << v << ' ' << u << ' ' << cnt << '\n';while(1){vcc[cnt].emplace_back(st[tp]);if(st[tp] == v) break;--tp;}--tp, vcc[cnt].emplace_back(u);}}else low[u] = min(dfn[v], low[u]);}
}
int getsz(int u){int sz = 1;on[u] = 1;for(int v : e[u]){if(!on[v]) sz += getsz(v); }return sz;
}
int main(){cin.tie(nullptr)->sync_with_stdio(0);cin >> n >> m;pw[0] = 1;for(int i = 1; i <= n; ++i) (pw[i] = pw[i - 1] * 2) %= mod;for(int i = 1; i <= m; ++i){int u, v;cin >> u >> v;e[u].emplace_back(v);e[v].emplace_back(u);}tarjan(1);for(int i = 1; i <= cnt; ++i){on.reset();for(int u : vcc[i]) on.set(u, 1);// cout << '\n';int c = vcc[i].size();for(int j = 0; j < c; ++j){int sz = getsz(vcc[i][j]);// cout << sz << ' ';val[j + 1] = pw[sz] - 1;}// cout << '\n';if(c == 2){ (ans += val[1] * val[2]) %= mod; continue; }for(int L = 1; L < c; ++L){for(int u = 1; u <= c; ++u){sumf[u - 1][0] = sumf[u - 1][1] = 0;sumf[u][0] = f[u][0] = val[u];sumf[u][1] = f[u][1] = 0;// cout << u << '\n';for(int v = u + 1; v <= c; ++v){int l = max(v - L, u - 1), dist;f[v][0] = (val[v] * (sumf[v - 1][0] - sumf[l][0])) % mod;l = max(v - L - 1, u - 1);f[v][1] = 0;if(v - L >= u) (f[v][1] = val[v] * (f[v - L][0] + sumf[v - 1][1] - sumf[l][1])) %= mod;if((dist = c - v + u) <= L){(ans += (c - L) * f[v][1]) %= mod;if(dist == L) (ans += (c - L) * f[v][0]) %= mod;}// cout << v << ' ' << f[v][0] << ' ' << f[v][1] << '\n';(sumf[v][0] = sumf[v - 1][0] + f[v][0]) %= mod;(sumf[v][1] = sumf[v - 1][1] + f[v][1]) %= mod;}}}}// cout << ans << '\n';cout << (ans * qpow(pw[n], mod - 2)) % mod;return 0;
}

P8100 [USACO22JAN] Counting Haybales P

考虑什么情况下 \(i\) 必须放在 \(j\) 的前面。由于只有 \(|h_i - h_{i + 1}| = 1\) 时才能交换两个数,并且认为相同的数之间不能交换。那么就可以考虑对于 \(i < j \land |h_i - h_j| \ne 1\) 都连一条 \((i,j)\) 的边,表示 \(i\) 必须放在 \(j\) 的前面。对这个 DAG 进行拓扑序计数,就是答案。
但是一般 DAG 是做不了的,发现奇偶的性质,即 \(h_i\) 为奇的和 \(h_i\) 为偶的实际上已经按原序列的顺序排好了。那么只用考虑两条链之间的拓扑限制。考虑 dp,\(dp_{i,j}\) 为第一条链前 \(i\) 个,第二条链前 \(j\) 个的方案数。如果发现 \(j + 1\) 的所有入边都在 \(\le i\) 的范围内了,那么就可以转移到 \(dp_{i, j + 1}\),表示这一位放 \(j + 1\)\(i + 1\) 同理。
这种考虑限制的想法可以稍微注意。

Code
#include <bits/stdc++.h>
using namespace std;
const int N = 5e3 + 5, mod = 1e9 + 7;
int n, a[N], dp[N][N], pos[2][N], pre[N], cnt[2];
void solve(){cin >> n;cnt[0] = cnt[1] = 0;for(int i = 1; i <= n; ++i){cin >> a[i];int x = a[i] & 1;pos[x][++cnt[x]] = i;pre[i] = 0;for(int j = i - 1; j >= 1; --j){if(x != (a[j] & 1) && abs(a[i] - a[j]) != 1){pre[i] = j;break;}}}dp[0][0] = 1;for(int i = 0; i <= cnt[0]; ++i){for(int j = 0; j <= cnt[1]; ++j){if(i == 0 && j == 0) continue;dp[i][j] = 0;if(i && pre[pos[0][i]] <= pos[1][j]) (dp[i][j] += dp[i - 1][j]) %= mod;if(j && pre[pos[1][j]] <= pos[0][i]) (dp[i][j] += dp[i][j - 1]) %= mod; }}cout << dp[cnt[0]][cnt[1]] << '\n';
}
signed main(){ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int T;cin >> T;while(T--) solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/917620.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3D 高斯训练速度和消耗 - MKT

3D 高斯训练速度和消耗 SEELE: A Unified Acceleration Framework for Real-Time Gaussian Splatting https://arxiv.org/pdf/2503.05168

做哪一类网站容易有排名中国建设银行网站会员注册信息补充

电脑崩溃之后&#xff0c;我发现维护系统还是很重要的一件事情。比如软件尽可能装D盘&#xff0c;C盘&#xff08;系统盘&#xff09;尽可能不要存储数据等等。接着&#xff0c;就是如何让系统更易用&#xff0c;因此我在这里分享我的使用方式&#xff0c;以后就可以随便重装系…

怎么设计个人网站在万网上域名了怎么做网站

目录 第一章、Java中的for循环介绍for循环for-each/增强for循环嵌套for循环 第一章、遍历List集合的几种方式简单的for循环增强型for循环Iterator迭代器ListIterator列表迭代器while循环Iterable.forEach()方法Stream.forEach()方法 第一章、Java中的for循环介绍 for循环 ①普…

完整教程:【PyTorch实战:文本分类】23、BERT文本分类实战指南:从原理到PyTorch落地

完整教程:【PyTorch实战:文本分类】23、BERT文本分类实战指南:从原理到PyTorch落地pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; …

Linux网络:运用UDP实现网络通信(网络套接字的创建绑定)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

常见进制

D:/study/C语言 devc/test9.c

9.25总结

今天是9.25,今天是星期四,今天上午上了一节数据结构和一节跆拳道课,跆拳道课上学了好多动作,还教我们劈叉,锻炼我们的韧带。下午就没有课程安排了,中午和朋友打了一会儿游戏,然后睡了一觉,醒来之后,去教室学了…

做受视频播放网站wordpress实现文章连载目录

感情是偏执的 越爱越是偏执的 不相信我看到的 硬要说裂缝不过 是皱褶 怎么先炽热的却先变冷了 慢热的却停不了还在沸腾着 看时光任性快跑随意就转折 慢冷的人啊 会自我折磨 冲动的人向来听不见挽留 这世界大得让你很难不旅游 浪漫让你温柔 也让你最惹人 泪流 …

proxifier联合burpsuite抓包小程序,但是小程序连不上网解决办法(亲测)

找了网上好多教程都没找到对应我这种情况的解决方法,我这个方法希望能帮到跟我情况一样的同学问题描述 之前看小迪的课程的时候学到过burpsuite加proxifier联合抓小程序的包,当时也复现成功了,后面在看到小程序资产…

完整教程:C语言——函数(超详细分析)

完整教程:C语言——函数(超详细分析)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mo…

大 LCP 时代(stupid.*)

大 LCP 时代(stupid.*) 题目描述 LCP 就是传说中的最长公共前缀,至于为什么要加上一个大字,那是因为…你会知道的(有大病)。 首先,求LCP就要有字符串。既然那么需要它们,那就给出n个字符串好了。 于是你需要回答…

网站中的滑动栏怎么做的四川建设网网

虚拟技术十分热门.虚拟技术是将一台物理硬件计算机虚拟成多台软件计算机.每一台虚拟出来的软件计算机(以下叫做虚拟机)用起来都就象是在用那台被虚拟的硬件计算机(以下叫做真实机)完全一样.当然这样的说法忽略了虚拟机相对于真实机在执行效益上不可避免所存在的损失.所以如何减…

实用指南:Python实现手榴弹爆炸算法(Grenade Explosion Method, GEM)(附完整代码)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Day08-C:\Users\Lenovo\Desktop\note\code\JavaSE\Basic\src\com\David\array-ArrayDemo01~07

数组首先要声明数组变量才能使用如dataType[] arrayRefVar; java语言中使用new操作来创建数组,如dataType[ ] arrayRefVar = new dataType[arraysize] 数组通过索引访问,索引从0开始内存分析堆:存放new的对象和数组…

yolov10_float16.tflite TO yolov10_int8.tflite

使用google colab平台1. 安装ultralytics!pip install ultralytics2. 导入yolo并从ultralytics加载yolov10n.ptfrom ultralytics import YOLO model = YOLO("https://github.com/ultralytics/assets/releases/dow…

ansible注意的和错误代码分析

一、需要注意的点分清楚这个是主控节点还是被控节点的操作,有的时候是一个文件从主控到被控节点,还是被控节点的文件到主控节点上面了剧本执行报错代码 # 仔细看,报错的原因就是ansibel_lvm 未定义,写错了变量名TA…

用 Rust 和 Tesseract OCR 识别验证码

一、背景介绍 Rust 是一种系统级编程语言,以性能和安全性著称。在自动化测试和数据分析场景中,验证码识别是一个常见挑战。结合 Tesseract OCR,我们可以使用 Rust 构建一个高效的验证码识别工具。本文将介绍如何使用…

基于寄存器地址amp;标准外设库的LED流水灯

实验任务2 1.1先在工程总文件夹中创建User,Library和Startup三个文件夹,然后右键keil中的文件夹Source Group 1添加工程所需的这三个文件夹。1.2分别在Library,Startup和User三个文件夹中添加必要的头文件和.c文件。…

用 Swift 和 Tesseract OCR 实现验证码识别

一、背景介绍 Swift 是 Apple 推出的现代化编程语言,广泛应用于 iOS 和 macOS 应用开发。结合 Tesseract OCR,可以在移动和桌面应用中高效地识别验证码。本文将展示如何使用 Swift 结合 Tesseract OCR 实现验证码自动…

Rust 和 Tesseract OCR 实现验证码识别

一、背景介绍 Rust 以其高性能和内存安全著称,适合构建高效的图像处理和 OCR 应用程序。本文将结合 Tesseract OCR,使用 Rust 实现验证码识别。 二、环境准备 2.1 安装 Rust 更多内容访问ttocr.com或联系1436423940 …