HDU1823 Luck and Love(二维线段树单点更新+区间查询+模板)

傷城~ 2022-06-10 08:28 323阅读 0赞

世界上上最远的距离不是相隔天涯海角
而是我在你面前
可你却不知道我爱你
―― 张小娴

前段日子,枫冰叶子给Wiskey做了个征婚启事,聘礼达到500万哦,天哪,可是天文数字了啊,不知多少MM蜂拥而至,顿时万人空巷,连扫地的大妈都来凑热闹来了。―_―|||
由于人数太多,Wiskey实在忙不过来,就把统计的事情全交给了枫冰叶子,自己跑回家休息去了。这可够枫冰叶子忙的了,他要处理的有两类事情,一是得接受MM的报名,二是要帮Wiskey查找符合要求的MM中缘分最高值。

Input

本题有多个测试数据,第一个数字M,表示接下来有连续的M个操作,当M=0时处理中止。
接下来是一个操作符C。
当操作符为‘I’时,表示有一个MM报名,后面接着一个整数,H表示身高,两个浮点数,A表示活泼度,L表示缘分值。 (100<=H<=200, 0.0<=A,L<=100.0)
当操作符为‘Q’时,后面接着四个浮点数,H1,H2表示身高区间,A1,A2表示活泼度区间,输出符合身高和活泼度要求的MM中的缘分最高值。 (100<=H1,H2<=200, 0.0<=A1,A2<=100.0)
所有输入的浮点数,均只有一位小数。

Output

对于每一次询问操作,在一行里面输出缘分最高值,保留一位小数。
对查找不到的询问,输出-1。

Sample Input

  1. 8
  2. I 160 50.5 60.0
  3. I 165 30.0 80.5
  4. I 166 10.0 50.0
  5. I 170 80.5 77.5
  6. Q 150 166 10.0 60.0
  7. Q 166 177 10.0 50.0
  8. I 166 40.0 99.9
  9. Q 166 177 10.0 50.0
  10. 0

Sample Output

  1. 80.5
  2. 50.0
  3. 99.9

题解:

题意:

如上诉所说

思路:

建一颗二维线段树,第一维是身高,由于没有低于100的,我们就可以把值减去99以缩减数组大小和更新查询的时间,然后由于第二维是活泼度是浮点型,我们就把值整体乘上10做成线段树,然后剩下的套模板就是了。。因为对二维线段树还不是很熟参考了别人的代码

代码:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <cstring>
  4. #include<math.h>
  5. #include<string>
  6. #include<stack>
  7. #include<queue>
  8. #include<list>
  9. #include<vector>
  10. #include <algorithm>
  11. using namespace std;
  12. #define INF 10086111
  13. #define lson k*2
  14. #define rson k*2+1
  15. #define M (l+r)/2
  16. int maxn[105*4][1005*4];
  17. int que;//询问结果
  18. int L1,L2,R1,R2;//因为数字比较多,开成全局就不用传来传去了,分别表示查询的身高区间和查询的活泼度区间
  19. void update1(int fk,int l,int r,int pos,int k,int v)//更新第二维,也就是活泼度,fk为第一维的节点下标
  20. {
  21. if(l==r)//如果搜到了要更新的位置,更新
  22. {
  23. maxn[fk][k]=max(maxn[fk][k],v);
  24. return;
  25. }
  26. int mid=M;
  27. if(pos<=mid)
  28. update1(fk,l,mid,pos,lson,v);
  29. else
  30. update1(fk,mid+1,r,pos,rson,v);
  31. maxn[fk][k]=max(maxn[fk][lson],maxn[fk][rson]);//更新父区间
  32. }
  33. void update2(int k,int l,int r,int pos1,int pos2,int v)//更新第一维,pos1为要插入的身高,pos2为活泼度,v为缘分值
  34. {
  35. update1(k,1,1000,pos2,1,v);//每到一次都要更新第二维
  36. if(l==r)
  37. return;
  38. int mid=M;
  39. if(pos1<=M)
  40. update2(lson,l,mid,pos1,pos2,v);
  41. else
  42. update2(rson,mid+1,r,pos1,pos2,v);
  43. }
  44. void query1(int l,int r,int k,int fk)//询问第二维,也就是活泼度
  45. {
  46. if(L2<=l&&r<=R2)//如果查到了要查询的子区间
  47. {
  48. que=max(que,maxn[fk][k]);//更新que
  49. return;
  50. }
  51. int mid=M;
  52. if(R2<=mid)
  53. query1(l,mid,lson,fk);
  54. else if(L2>mid)
  55. query1(mid+1,r,rson,fk);
  56. else
  57. {
  58. query1(l,mid,lson,fk);
  59. query1(mid+1,r,rson,fk);
  60. }
  61. }
  62. void query2(int l,int r,int k)//查询第一维,身高
  63. {
  64. if(L1<=l&&r<=R1)//查好了第一维
  65. {
  66. query1(1,1000,1,k);//查第二维
  67. return;
  68. }
  69. int mid=M;
  70. if(R1<=mid)
  71. query2(l,mid,lson);
  72. else if(L1>mid)
  73. query2(mid+1,r,rson);
  74. else
  75. {
  76. query2(l,mid,lson);
  77. query2(mid+1,r,rson);
  78. }
  79. }
  80. int main()
  81. {
  82. int i,j,k,n;
  83. int a,b,v,h,h1,h2;
  84. double e,o,e1,e2;
  85. char s[10];
  86. while(scanf("%d",&n)!=EOF&&n)
  87. {
  88. memset(maxn,-1,sizeof(maxn));//初始化-1
  89. while(n--)
  90. {
  91. scanf("%s",s);
  92. if(s[0]=='I')
  93. {
  94. scanf("%d%lf%lf",&h,&e,&o);
  95. a=h-99;//减去以节省时间空间
  96. b=e*10;//乘上10做成线段树
  97. v=o*10;
  98. update2(1,1,100,a,b,v);
  99. }
  100. else
  101. {
  102. scanf("%d%d%lf%lf",&h1,&h2,&e1,&e2);
  103. if(h1>h2)//防止有坑
  104. swap(h1,h2);
  105. if(e1>e2)
  106. swap(e1,e2);
  107. L1=h1-99;
  108. R1=h2-99;
  109. L2=e1*10;
  110. R2=e2*10;
  111. que=-1;
  112. query2(1,100,1);
  113. if(que==-1)
  114. printf("-1\n");
  115. else
  116. printf("%d.%d\n",que/10,que%10);
  117. }
  118. }
  119. }
  120. return 0;
  121. }

发表评论

表情:
评论列表 (有 0 条评论,323人围观)

还没有评论,来说两句吧...

相关阅读