当前位置: 首页 > 网络知识

[luoguP3960] 列队(动态开点线段树)

时间:2026-01-29 09:38:42

传送门

有splay的做法,有树状数组的做法。。。

最好理解的还是线段树的做法。

一开始我是这样想的,如果移动某一个人,只有当前行和最后一列会受到影响,感觉就像是个线段树,树状数组什么的。

然而接下来就想歪了,把一个人移到后面,等于把后面的整体往前移一格,gg

正确思路是权值线段树,如果一个数被移走,相当于这个数的个数1,然后把它变成了m+1,放到后面。

移动第x行第y个人其实就是求第x行的第y大。

这样,每一行和最后一列建一棵线段树,然而超空间。

所以需要动态开点,因为总共只移动3*10^5次,也就是开nlongn的点。

据说逆向思维可以骗50分,这都没想到。。。

最后附上丑陋的,调了一晚上的,连我自己都看不懂的代码——

#include <cstdio>#include <cstring>#include <iostream>#define N 600001#define LL long longusing namespace std;int n, m, q, M, cnt;int size[N], sum[N * 10], ls[N * 10], rs[N * 10], root[N];LL val[N * 10];inline int read()inline LL del(int &now, int l, int r, int x, int f, int h)int mid = (l + r) >> 1;if(mid  l + 1 + sum[ls[now]] >= x) return del(ls[now], l, mid, x, f, h);else return del(rs[now], mid + 1, r, x  (mid  l + 1 + sum[ls[now]]), f, h); }inline void insert(int &now, int l, int r, int x, LL d)int mid = (l + r) >> 1;if(x <= mid) insert(ls[now], l, mid, x, d);else insert(rs[now], mid + 1, r, x, d);}int main()++size[0];insert(root[0], 1, M, size[0], a);}return 0;}

  

就让这个题作为我回归奥赛的开端,SDOI2018加油!



上一篇:[luoguP3317] [SDOI2014]重建(矩阵树定理)
下一篇:[luoguP2157] [SDOI2009]学校食堂Dining(状压DP)
树状数组 线段树 splay
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器
  • 英特尔第五代 Xeon CPU 来了:详细信息和行业反应
  • 由于云计算放缓引发扩张担忧,甲骨文股价暴跌
  • Web开发状况报告详细介绍可组合架构的优点
  • 如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳
  • 美光在数据中心需求增长后给出了强有力的预测
  • 2027服务器市场价值将接近1960亿美元
  • 生成式人工智能的下一步是什么?
  • 分享在外部存储上安装Ubuntu的5种方法技巧
  • 全球数据中心发展的关键考虑因素
  • 英特尔与 Vertiv 合作开发液冷 AI 处理器

    英特尔第五代 Xeon CPU 来了:详细信息和行业反应

    由于云计算放缓引发扩张担忧,甲骨文股价暴跌

    Web开发状况报告详细介绍可组合架构的优点

    如何使用 PowerShell 的 Get-Date Cmdlet 创建时间戳

    美光在数据中心需求增长后给出了强有力的预测

    2027服务器市场价值将接近1960亿美元

    生成式人工智能的下一步是什么?

    分享在外部存储上安装Ubuntu的5种方法技巧

    全球数据中心发展的关键考虑因素