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

真的好怪题解:P14314 [Aboi Round 2] Oneshot

来一篇真的好怪的题解。

正文

首先有一个很低级的做法,就是每次询问直接拉出来 \(\frac np\) 个数,然后排好序,用另外 \(\frac nq\) 个数在那上面二分就结束了。

这样做的复杂度是 \(\mathcal{O}(nm\log n)\)

然后我们记忆化一下,发现小的 \(q,p\) 出现次数不会很多,就很好,至于复杂度我就不会算了。

不知道有多少分。

然后虽然不知道复杂度是多少但是总之考虑砍掉 \(\log\)

考虑阈值分治,定义阈值 \(B\)

给小于 \(B\)\(q,p\) 提前处理好排过序的数组,这样复杂度就优很多,定义阈值为 \(\log n\) 就可以砍掉 \(\log\),不过显然阈值拉高一点是好的。

考虑继续优化复杂度。

不过我们可以先尝试交一发。

结果就 AC 了。

所以就不优化复杂度了,反正我也不会算,就当它是对的算了。

代码

// code by 樓影沫瞬_Hz17
#include <bits/extc++.h>using namespace std;
constexpr int N = 5e4 + 10, B = 100; // 随便乱设的阈值uint n, m;
uint16_t a[N];uint16_t *wer[B + 10][B + 10], *ed[B + 10][B + 10];
uint16_t wsz[B + 10][B + 10]; // 因为一些原因我对 vector 有阴影了,所以不用,我选择手写
using puu = pair<uint, uint>;
puu b[N];using __gnu_pbds::gp_hash_table; // 好长的记忆化数组…………
gp_hash_table<uint16_t, gp_hash_table<uint16_t, gp_hash_table<uint16_t, unordered_map<uint16_t, uint> > > > ans;
uint16_t tmp1[N], tmp2[N]; // 相当于提前申请点内存signed main() {#ifndef ONLINE_JUDGEfreopen("in.ru", "r", stdin);freopen("out.ru", "w", stdout);#endifios::sync_with_stdio(0), cin.tie(0), cout.tie(0);cin >> n >> m;for(uint i = 1; i <= n; i ++) cin >> a[i], b[i] = {a[i], i};sort(b + 1, b + 1 + n, [](const puu &a, const puu &b) { return a.first < b.first; }); // 现在排了,一会省点排序for(uint p = 1; p <= B; p ++) for(uint i = 1; i <= n; i ++) wsz[p][i % p] ++; for(uint p = 1; p <= B; p ++) for(uint les = 0; les < p; les ++) wer[p][les] = ed[p][les] = new uint16_t[wsz[p][les] + 10];for(uint p = 1; p <= B; p ++) for(uint i = 1; i <= n; i ++) *ed[p][b[i].second % p] ++ = b[i].first; // 省在这了auto PreCalc = [](uint16_t *st1, uint16_t *ed1, uint16_t *st2, uint16_t *ed2) -> puu {uint res1 = 0, res2 = 0, ct1 = 0, ct2 = 0;// 如果两个数组都有序就直接归并,别二分了while(st1 != ed1 and st2 != ed2) {while(*st1 < *st2 and st1 != ed1) res1 += ct2, st1 ++, ct1 ++;while(*st1 == *st2 and st1 != ed1) res1 += ct2, st1 ++, ct1 ++, res2 --;while(*st2 < *st1 and st2 != ed2) res2 += ct1, st2 ++, ct2 ++;}while(st2 != ed2) res2 += ct1, st2 ++;while(st1 != ed1) res1 += ct2, st1 ++;return {res1, res2};}; // 本来打算预处理所以函数名叫预处理uint16_t p, x, q, y;while(m --) {cin >> p >> x >> q >> y;if(ans[p][q][x].count(y)) cout << ans[p][q][x][y] << '\n';else if(p <= B and q <= B) { // 分类讨论好长啊…………auto [res1, res2] = PreCalc(wer[p][x], ed[p][x], wer[q][y], ed[q][y]);ans[p][q][x][y] = res2;ans[q][p][y][x] = res1;cout << ans[p][q][x][y] << '\n';}else { uint ans = 0; if(p <= B) { // 好长啊…………uint16_t *st1 = wer[p][x], *ed1 = ed[p][x];for(uint i = y == 0 ? q : y; i <= n; i += q) ans += lower_bound(st1, ed1, a[i]) - st1;}else if(q <= B) { // 好长啊…………uint16_t *st2 = wer[q][y], *ed2 = ed[q][y];for(uint i = x == 0 ? p : x; i <= n; i += p) ans += ed2 - upper_bound(st2, ed2, a[i]);}else { // 真的好长啊…………uint16_t *st1 = tmp1, *ed1 = tmp1;for(uint i = x == 0 ? p : x; i <= n; i += p) *ed1 ++ = a[i];sort(st1, ed1);for(uint i = y == 0 ? q : y; i <= n; i += q) ans += lower_bound(st1, ed1, a[i]) - st1;}::ans[p][q][x][y] = ans;cout << ans << '\n';}}
}
http://www.jsqmd.com/news/47821/

相关文章:

  • ElasticSearch索引库操作 - 努力-
  • 2025年集成房屋设计公司十大排名,岗亭加工厂家十大排行榜,专业岗亭定制工厂怎么选?彩钢移动厕所厂家推荐。
  • 礼盒拖车公司推荐,礼盒拖车定制公司排行榜,礼盒拖车厂家口碑推荐,礼盒拖车生产厂家-航利通达
  • 360笔试
  • 图像的颜色模式
  • .NET+AI | MEAI | Function Caling 实操(4)
  • 高频变压器公司口碑榜单,电感公司技术排名,电感厂家交付效率排名,磁性元器件公司客户推荐,电感器公司产能排名,线圈公司行业排名-汉翔电子
  • MinIo介绍 - 努力-
  • BLOG1
  • host with linux
  • sguardsvc64.exe(Anti-Cheat Expert)驱动不兼容导致无法开启“内核模式硬件强制堆栈保护”或“内存完整性”
  • Wi-Fi FTM 技术 10 年后展望
  • Docker使用【镜像】 - 指南
  • 20251122
  • 2025年11月22日训练赛
  • Python 潮流周刊#128:将 Rust 语言引入 CPython
  • NCHU_单部电梯调度程序总结blogs
  • 电梯调度程序分析
  • Hive动态分区怎样减少存储压力
  • 面向对象程序设计——单元总结
  • Linux命令绕过 - 教程
  • 帮同学签了个到,我发现竟然能盗光他所有账号
  • MyBatis Flex 讲解使用
  • Catalog
  • NCHU_Blog1_刘素萍_单部电梯调度程序
  • 同花顺通达信常用颜色图标
  • hive sql开发难不难
  • 数学的大厦(五):除法、有理数、等价关系
  • KingbaseES电科金仓数据库SQL调优 - 实践
  • 一种自定义二维码的加码、解码、识别和绘制算法的逆向和重构