牛客多校第3场 J 思维+树状数组+二分

传送门:https://ac.nowcoder.com/acm/contest/883/J

题意:

给你q个询问,和一个队列容量f

询问有两种操作:

0.访问操作,如果询问的name在队列中存在的话,那么就输出队列中name对应的val值,然后将队列中name对应的元素扔到队列的尾部去,否则就直接将该元素插入到队列的尾部去

1.插入操作,得到队列中对应的name元素的v值为k,查询第k+v个元素的v值是多少

题解:

已知,对于插入操作,我们需要很快的查询对应的name值的val

所以我们考虑map映射,为了解决string过慢的问题,我们将stringhash成一个unsigned long long的值

我们记录有多少个数被插入了,还有每个点的绝对坐标,如果在0操作中 点x被丢弃了,那么我们就对x位置打上标记1,这样,在我们查询第y个操作时,实际上,这个y操作对于的位置就是 查询这个y对应的pos位减去当前位置之前被删掉的数的和加上 v值

我们用tot统计被插入数的数量,因为一开始就是空串,所以tot实际上就代表队列中有多少个数,如果tot>m,我们就丢弃队头的元素

对于每次查询,我们是找当前位置向左的位置,因为我们删除的数实际上只是给打上了一个+1的标记,所以我们需要找到左边真正存在的那个数,这个右端点不太好找,所以我们考虑二分,二分当前位置是否是第r个点

check就直接用二分出来的mid减去mid之前的丢弃的个数,如果这个个数>当前个数,那么就改变二分的上界r,否则改变二分的下界l

然后就可以得到满足真正的pos+1的位置的值的数了

emmm复杂度应该是两个log 被卡map的操作然后有迭代器 实现mp的操作,这样卡过去了 600+ms 海星吧

代码:

  1. #include <set>
  2. #include <map>
  3. #include <stack>
  4. #include <cmath>
  5. #include <queue>
  6. #include <cstdio>
  7. #include <string>
  8. #include <vector>
  9. #include <cstring>
  10. #include <iostream>
  11. #include <algorithm>
  12. #include <unordered_map>
  13. #include <assert.h>
  14. using namespace std;
  15. typedef long long LL;
  16. typedef pair<int, int> pii;
  17. typedef unsigned long long uLL;
  18. #define ls rt<<1
  19. #define rs rt<<1|1
  20. #define lson l,mid,rt<<1
  21. #define rson mid+1,r,rt<<1|1
  22. #define bug printf("*********\n")
  23. #define FIN freopen("input.txt","r",stdin);
  24. #define FON freopen("output.txt","w+",stdout);
  25. #define IO ios::sync_with_stdio(false),cin.tie(0)
  26. #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
  27. #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
  28. #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
  29. const int maxn = 5e5 + 5;
  30. const int INF = 0x3f3f3f3f;
  31. const int mod = 1e9 + 7;
  32. const double Pi = acos(-1);
  33. const int seed = 1331;
  34. LL quick_pow(LL x, LL y) {
  35. LL ans = 1;
  36. while(y) {
  37. if(y & 1) {
  38. ans = ans * x % mod;
  39. } x = x * x % mod;
  40. y >>= 1;
  41. } return ans;
  42. }
  43. int lowbit(int x) {
  44. return x & (-x);
  45. }
  46. int bit[maxn];
  47. void add(int pos, int val) {
  48. while(pos < maxn) {
  49. bit[pos] += val;
  50. pos += lowbit(pos);
  51. }
  52. }
  53. int query(int pos) {
  54. int res = 0;
  55. while(pos) {
  56. res += bit[pos];
  57. pos -= lowbit(pos);
  58. }
  59. return res;
  60. }
  61. void clear(int pos, int MM) {
  62. while(pos < MM) {
  63. bit[pos] = 0;
  64. pos += lowbit(pos);
  65. }
  66. }
  67. uLL Hash(char *x) {
  68. uLL h = 0;
  69. for(int i = 0; x[i]; i++) {
  70. h = h * seed + x[i];
  71. }
  72. return h;
  73. }
  74. int op;
  75. int v;
  76. int val[maxn];
  77. uLL hname[maxn];
  78. char name[20];
  79. map<uLL, int> mp;
  80. int get_pos(int p, int tot) { //虽然名字是tot,但是要传入index
  81. int pos = -1;
  82. int l = 1, r = tot;
  83. while(r >= l) {
  84. int mid = (l + r) / 2;
  85. int num = mid - query(mid);
  86. if(num >= p) {
  87. r = mid - 1;
  88. pos = mid;
  89. } else {
  90. l = mid + 1;
  91. }
  92. }
  93. assert(pos != -1);
  94. return pos;
  95. }
  96. map<uLL, int>:: iterator iter;
  97. int main() {
  98. int T;
  99. scanf("%d", &T);
  100. while(T--) {
  101. mp.clear();
  102. int m, k;
  103. scanf("%d%d", &k, &m);
  104. memset(bit, 0, sizeof(bit));
  105. int Index = 0;
  106. int tot = 0;
  107. for(int i = 1; i <= k; i++) {
  108. scanf("%d%s%d", &op, name, &v);
  109. uLL h = Hash(name);
  110. iter = mp.find(h);
  111. if(op == 0) {
  112. if(iter != mp.end()) {
  113. int pos = iter->second;
  114. printf("%d\n", val[pos]);
  115. add(pos, 1);
  116. Index++;//charu
  117. hname[Index] = h;
  118. val[Index] = val[pos];
  119. iter->second = Index;
  120. } else {
  121. printf("%d\n", v);
  122. tot++;
  123. if(tot > m) {
  124. tot--;
  125. int pos = get_pos(1, Index);
  126. add(pos, 1);
  127. iter = mp.find(hname[pos]);
  128. if(iter != mp.end())mp.erase(iter);
  129. }
  130. Index++;
  131. mp[h] = Index;
  132. hname[Index] = h;
  133. val[Index] = v;
  134. }
  135. } else {
  136. if(iter == mp.end()) {
  137. printf("Invalid\n");
  138. continue;
  139. }
  140. int vv = iter->second;
  141. int pos = vv - query(vv - 1);
  142. pos += v;
  143. if(pos > tot || pos < 1) {
  144. printf("Invalid\n");
  145. } else {
  146. pos = get_pos(pos, Index);
  147. printf("%d\n", val[pos]);
  148. }
  149. }
  150. }
  151. }
  152. return 0;
  153. }

牛客多校第3场 J 思维+树状数组+二分的更多相关文章

  1. 18牛客多校训练第二场 J farm

    题意:一个n×m的农田, 每个小格子都有一种作物, 现在喷t次农药,每次农药覆盖一个矩形, 该矩形里面与农药类型不同的植物都会死掉, 求最后植物的死亡数是多少. 题解:二维树状数组. 每次喷农药的时候 ...

  2. 牛客网 牛客练习赛4 A.Laptop-二维偏序+离散化+树状数组

    A.Laptop 链接:https://ac.nowcoder.com/acm/contest/16/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其 ...

  3. 牛客练习赛47 E DongDong数颜色 (树状数组维护区间元素种类数)

    链接:https://ac.nowcoder.com/acm/contest/904/E 来源:牛客网 DongDong数颜色 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 5242 ...

  4. 「BZOJ1669」D 饥饿的牛 [Usaco2006 Oct] Hungry Cows 牛客假日团队赛5 (LIS,离散化树状数组)

    链接:https://ac.nowcoder.com/acm/contest/984/D 来源:牛客网 饥饿的牛 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言 ...

  5. 牛客训练六:海啸(二维树状数组+vector函数的使用)

    题目链接:传送门 思路: 二维树状数组, vector(first,last)函数中assign函数相当于将first中的函数清空,然后将last中的值赋值给first. 参考文章:传送门 #incl ...

  6. 牛客多校第五场 J:Plan

    链接:https://www.nowcoder.com/acm/contest/143/J 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...

  7. 牛客多校第六场 J Heritage of skywalkert 随即互质概率 nth_element(求最大多少项模板)

    链接:https://www.nowcoder.com/acm/contest/144/J来源:牛客网 skywalkert, the new legend of Beihang University ...

  8. 牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)

    题目传送门:https://www.nowcoder.com/acm/contest/142/J 题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法. 分析: eg.对于序列{ ...

  9. 2019牛客多校第四场J free——分层图&&最短路

    题意 一张无向图,每条边有权值,可以选择不超过 $k$ 条路使其权值变成0,求 $S$ 到 $T$ 的最短路.(同洛谷 P4568) 分析 首先,分层图最短路可以有效解决这种带有 「阶段性」的最短路, ...

随机推荐

  1. 解决VS+Qt不生成moc文件问题

    使用VS的Qt插件进行Qt开发时,有时候会遇到不能生成moc文件的问题. 1.在工程中可以看到这个Generated files目录下是有一个看似moc文件的文件,双击打开的话: 如果能正常打开,文件 ...

  2. 中国境内PE\VC\投资公司名单

    中国境内PE\VC\投资公司名单 1.青云创投 2.高盛 3.红杉资本 4.鼎晖创投 5.枫丹国际 6.派杰投资银行 7.凯雷投资 8.长安私人资本 9.格林雷斯 10.汉能资本 11.启明创投 12 ...

  3. 关于 KiCad 画圆弧走线

    关于 KiCad 画圆弧走线 有很多关于 关于 KiCad 画圆弧走线的帖子. 最新进展是 V6 在开发中. 但是因为关于 DRC 问题,开发好像有难度. https://bugs.launchpad ...

  4. lattice planner 规划详解

    大家好,我是来自百度智能驾驶事业群的许珂诚.今天很高兴能给大家分享Apollo 3.0新发布的Lattice规划算法. Lattice算法隶属于规划模块.规划模块以预测模块.routing模块.高精地 ...

  5. Redis源码解析:08对象

    前面介绍了Redis用到的所有主要数据结构,比如简单动态字符串(SDS).双端链表.字典.压缩列表.整数集合等.然而Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一 ...

  6. jquery attr()和prop()方法的区别

    $('').attr()返回的是html对象 $('').prop()返回的是DOM对象 attr(): attr() 方法设置或返回被选元素的属性和值. 当该方法用于返回属性值,则返回第一个匹配元素 ...

  7. jQuery仿迅雷图片轮换效果

    jQuery仿迅雷图片轮换效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...

  8. 前端知识体系(二)http请求

    https://blog.csdn.net/Lammonpeter/article/details/81358387 一.DNS解析 首先DNS域名系统的作用是将输入的url域名解析成ip地址以方便对 ...

  9. jqLite

    一.关于DOM导航的jqLite方法 children() 返回一组子元素.这个方法的jqLite实现不支持jQuery所提供的选择器特性 eq(index) 从一个元素集合中返回指定索引下的元素 f ...

  10. uva 12296 Pieces and Discs (Geometry)

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...