传送门

题目分析

在只打会主席树模板的情况下做了这道题,也算是深有体会。

首先任务可以差分:一个任务是(s, e, p), 则在s处+1, 在e+1处-1,符合前缀。但是我们要查询指定时间的前k任务之和,可以想到主席树,且符合差分性质。

1~n每个节点代表从开始时间到现在,每个节点下是一颗权值线段树。用建立主席树的方法先将新时间节点置为前一个时间(从前一个时间更新),再将当前时间的所有差分操作更新(从当前时间更新),得到的每个时间节点便是从开始到此时间的一颗权值线段树。刚开始本来打的指针,调试被逼无奈改为数组(真·好写)。

建好树过后,对于查询(x, k), 就在x时间节点的这颗权值线段树上查询前k个元素之和,线段树的查询就不赘述了,详见代码。

另外,空间真的是个迷,卡了半天RE。

code

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 1000005;
  4. typedef long long ll;
  5. int n, c[N * 4], lenc, m;
  6. int p[N], taskCnt, maxx = -1, rt[N];
  7. struct TASK{
  8. int point, tag, id;
  9. inline bool operator < (const TASK &b) const{
  10. return point < b.point;
  11. }
  12. }task[N];
  13. struct node{
  14. int lc, rc;
  15. ll sum, cnt;
  16. node(){}
  17. }tr[N * 15];
  18. int pool;
  19. vector<int> lists[N];
  20. inline int read(){
  21. int i = 0, f = 1; char ch = getchar();
  22. for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
  23. if(ch == '-') f = -1, ch = getchar();
  24. for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
  25. return i * f;
  26. }
  27. inline void wr(ll x){
  28. if(x < 0) putchar('-'), x = -x;
  29. if(x > 9) wr(x / 10);
  30. putchar(x % 10 + '0');
  31. }
  32. inline void disc_init(){
  33. sort(c + 1, c + lenc + 1);
  34. lenc = unique(c + 1, c + lenc + 1) - (c + 1);
  35. for(int i = 1; i <= m; i++) p[i] = lower_bound(c + 1, c + lenc + 1, p[i]) - c;
  36. }
  37. inline void insert(int x, int &y, int l, int r, int v, int cnt){
  38. tr[y = ++pool] = tr[x];
  39. tr[y].sum += cnt * c[v], tr[y].cnt += cnt;
  40. if(l == r) return;
  41. int mid = l + r >> 1;
  42. if(v <= mid) insert(tr[x].lc, tr[y].lc, l, mid, v, cnt);
  43. else insert(tr[x].rc, tr[y].rc, mid + 1, r, v, cnt);
  44. }
  45. inline ll query(int p, int l, int r, int k){
  46. if(tr[p].cnt <= k) return tr[p].sum;
  47. if(l == r) return c[l];
  48. int mid = l + r >> 1;
  49. if(k <= tr[tr[p].lc].cnt) return query(tr[p].lc, l, mid, k);
  50. else return query(tr[p].rc, mid + 1, r, k - tr[tr[p].lc].cnt) + tr[tr[p].lc].sum;
  51. }
  52. int main(){
  53. m = read(), n = read();
  54. for(int i = 1; i <= m; i++){
  55. task[++taskCnt].point = read(), task[taskCnt].tag = 1, task[taskCnt].id = i, lists[task[taskCnt].point].push_back(taskCnt);
  56. task[++taskCnt].point = read() + 1, task[taskCnt].tag = -1, task[taskCnt].id = i, lists[task[taskCnt].point].push_back(taskCnt);
  57. p[i] = c[++lenc] = read();
  58. }
  59. disc_init();
  60. for(int i = 1; i <= n; i++){
  61. insert(rt[i - 1], rt[i], 1, lenc, 0, 0);
  62. for(int j = 0; j < lists[i].size(); j++)
  63. insert(rt[i], rt[i], 1, lenc, p[task[lists[i][j]].id], task[lists[i][j]].tag);
  64. }
  65. ll pre = 1, ans;
  66. for(int i = 1; i <= n; i++){
  67. int x = read(), a = read(), b = read(), c = read();
  68. ans = query(rt[x], 1, lenc, ((a * pre + b) % c) + 1);
  69. wr(ans), putchar('\n');
  70. pre = ans;
  71. }
  72. }

BZOJ 3932 - 主席树的更多相关文章

  1. bzoj 1901 主席树+树状数组

    修改+查询第k小值 单纯主席树修改会打乱所有,所以再套一个树状数组维护前缀和使得修改,查询都是log 对了,bzoj上不需要读入组数,蜜汁re.. #include<cstdio> #in ...

  2. BZOJ 2588 主席树

    思路: 主席树 做完BZOJ 3123 觉得这是道水啊-- 然后狂RE 狂MLE 要来数据 忘把deep[1]设成1了----------. 啊wocccccccccccccccc //By Siri ...

  3. bzoj 1818 主席树

    思路:主席树搞一搞. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #de ...

  4. BZOJ 4771 主席树+倍增+set

    思路: 因为有深度的限制,并且我们是在线段树上维护权值,所以我们把点按照dep排序,然后一个一个修改...主席树的下标就是dfs序,子树的查询就是区间查询... 但是发现这样怎么去维护LCA呢...因 ...

  5. BZOJ 3674/BZOJ 3673 主席树

    思路: 主席树维护可持久化数组 剩下的就是普通的并查集了- //By SiriusRen #include <cstdio> #include <cstring> #inclu ...

  6. BZOJ 3123 主席树 启发式合并

    思路: 主席树 搞树上的k大 x+y-lca(x,y)-fa(lca(x,y)) 按照size小树往大树上插 启发式合并 n*log^2n的 搞定~ //By SiriusRen #include & ...

  7. BZOJ 4448 主席树+树链剖分(在线)

    为什么题解都是离线的-- (抄都没法抄) 搞一棵主席树 1 操作 新树上的当前节点设成1 2 操作 查max(i-xx-1,0)那棵树上这条路径上有多少个点是1 让你找经过了多少个点 查的时候用dee ...

  8. BZOJ 3524主席树裸题 (雾)

    思路: 按权值建一棵主席树 (但是这好像不是正解 空间复杂度是不对的--.) //By SiriusRen #include <cstdio> #include <cstring&g ...

  9. BZOJ 3524 - 主席树

    传送门 题目分析 标准主席树,按照位置插入每个数,对于询问l, r, 在l-1,r两树上按照线段树搜索次数大于(r - l + 1) / 2的数. code #include<bits/stdc ...

随机推荐

  1. POJ 3134 - Power Calculus (IDDFS)

    题意:求仅仅用乘法和除法最快多少步能够求到x^n 思路:迭代加深搜索 //Accepted 164K 1094MS C++ 840B include<cstdio> #include< ...

  2. iOS_02_什么是ios开发

    什么是ios开发? * 已知:ios是iphone,ipad等手持设备操作系统. * ios开发就是开发运行在ios系统上的应用或者游戏软件,比如手机QQ,微博或者游戏,说白了,就是开发手机软件:当然 ...

  3. 关于Android中设置闹钟的相对完善的解决方案

    前些时候,有人在我「非著名程序员」微信公众号的后台问我有没有设置闹钟的demo,我当时说承诺为大家写一个,一直没空,直到最近又有人跟我要,我决定抽时间写一个吧.确实设置闹钟是一个比较麻烦的东西.我在这 ...

  4. Eclipse下配置Ant脚本 自己主动打包带签名的Android apk

    尽管eclipse非常少用了,可是在古老的项目上还是会用到.一个麻烦事是打带签名包的时候.非常不方便.下边纪录下配置ant,自己主动打包带签名apk的过程,作为备忘.(PC环境为MAC) 1,第一步得 ...

  5. 简要分析unity3d中剪不断理还乱的yield

    在学习unity3d的时候非常easy看到以下这个样例: void Start () { StartCoroutine(Destroy()); } IEnumerator Destroy(){ yie ...

  6. js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();)

    js进阶解决浏览器缓存不能自动更新的问题(在ajax的url上带上一个参数,可以是日期,或者是随机数)(随机数Math.random)(取得日期的毫秒数:new Date().getTime();) ...

  7. ListView.setSelection(position)不起作用

    选择同事列表页面,在Adapter里设置复选框背景时调用了notifyDataSetChanged(),阻碍了UI线程,因此在设置ListView.setSelection(position)时不起作 ...

  8. Synopsys工艺库札记

    Synopsys工艺库札记 库的基本信息 库类 库类语句指定库名. library ( smic13HT_ss ) { ... <lirary description> ... } /*e ...

  9. 将Sublime Text2 加入右键菜单

    在googleread里面看有人推荐sublime text2.说开发很方便.就下载一个试试.写html还真的挺爽. 于是按照vim加入鼠标右键的方法.果然可以.这里和大家分享 1. 运行中输入 re ...

  10. jQuery中serializeArray方法的使用及对象与字符串的转换

    使用jQuery中的serializeArray()方法可以方便的将表单中的各个信息,转化为多个{name:xx,value:xx}对象的数组, 再使用遍历的方式可以方便的将数组转化为json对象, ...