一、题意

给定一个序列,之后给出若干个修改,修改的内容为在原序列的基础上,将某一位元素的值改成给定的值<每次修改相互独立,不保存修改后的结果>。之后询问,在选择第一位元素的情况下,最长递增子序列的长度是多少。

二、题解

考虑不经修改的情况,应当设dp[i]为选取当前位情况下的最长递增子串的长度。则对于这道题,应当认为对于修改a为b,设l_pos为a左边最大的元素的位置,r_pos为a右边大于max(b,r_pos)的元素的位置。则有ans = dp[1] - dp[l_pos] + 1 + dp[r_pos];对于b本身大于位于l_pos的元素,应当给结果+1。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define ll long long
  5.  
  6. const int MAXN = ;
  7.  
  8. class Node{
  9. public:
  10. int l,r,lc,rc,maxx;
  11. };
  12. Node nodes[MAXN];
  13. int nodes_num;
  14. int t,n,m;
  15.  
  16. int arr[MAXN];
  17. int dp[MAXN];
  18.  
  19. void tree_init(int a,int b){
  20. int now = nodes_num++;
  21. nodes[now].l = a;
  22. nodes[now].r = b;
  23. if(a == b-){
  24. nodes[now].maxx = arr[a];
  25. return ;
  26. }
  27. int mid = (a+b)/;
  28. nodes[now].lc = nodes_num;
  29. tree_init(a,mid);
  30. nodes[now].rc = nodes_num;
  31. tree_init(mid,b);
  32. nodes[now].maxx = max(nodes[nodes[now].lc].maxx,nodes[nodes[now].rc].maxx);
  33. }
  34.  
  35. int find_max(int now){
  36. int l = nodes[now].l;
  37. int r = nodes[now].r;
  38. if(l == r-)return l;
  39. int maxx = nodes[now].maxx;
  40. int lc = nodes[now].lc;
  41. int rc = nodes[now].rc;
  42. if(maxx == nodes[lc].maxx)return find_max(lc);
  43. else return find_max(rc);
  44. }
  45.  
  46. int find_biggest(int now,int a,int b){
  47. int l = nodes[now].l;
  48. int r =nodes[now].r;
  49. if(l == a&&r == b){
  50. return find_max(now);
  51. }
  52. int mid = (l+r)/;
  53. int ret ;
  54. int lc = nodes[now].lc;
  55. int rc = nodes[now].rc;
  56. if(a<mid){
  57. ret = find_biggest(lc,a,min(b,mid));
  58. if(b>mid){
  59. int tmp = find_biggest(rc,mid,b);
  60. ret = arr[ret] >= arr[tmp] ? ret:tmp;
  61. }
  62. }else ret = find_biggest(rc,a,b);
  63. return ret;
  64. }
  65.  
  66. int find_left(int now,int key){
  67. int l = nodes[now].l;
  68. int r = nodes[now].r;
  69. if(l == r-)return l;
  70. int lc = nodes[now].lc;
  71. int rc = nodes[now].rc;
  72. if(nodes[lc].maxx > key)return find_left(lc,key);
  73. else return find_left(rc,key);
  74. }
  75.  
  76. int find_first(int now,int pos, int key){
  77. int l = nodes[now].l;
  78. int r = nodes[now].r;
  79. if(l >= pos){
  80. return find_left(now,key);
  81. }
  82. int mid = (l+r)/;
  83.  
  84. int lc = nodes[now].lc;
  85. int rc = nodes[now].rc;
  86. int ret ;
  87. if(pos < mid && nodes[lc].maxx > key){
  88. ret = find_first(lc,pos,key);
  89. if(ret >= pos && arr[ret] > key)return ret;
  90. }
  91. if(nodes[rc].maxx <= key)return r-;
  92. return find_first(rc,pos,key);
  93.  
  94. }
  95.  
  96. void init(){
  97. scanf("%d %d",&n,&m);
  98. nodes_num = ;
  99. arr[] = -;
  100. arr[n+] = INT_MAX;
  101. for(int i=;i<=n;++i)scanf("%d",&arr[i]);
  102. tree_init(,n+);
  103. memset(dp,,sizeof(dp));
  104. for(int i=n;i>=;--i){
  105. dp[i] = dp[find_first(,i+,arr[i])]+;
  106. }
  107. dp[] = dp[]+;
  108. for(int i=;i<m;++i){
  109. int a,b;
  110. scanf("%d %d",&a,&b);
  111. int l_pos = find_biggest(,,a);
  112. int key = max(b,arr[l_pos]);
  113. int r_pos = find_first(,a+,max(b,arr[l_pos]));
  114. int ans = dp[] - dp[l_pos] + + dp[r_pos];
  115. if(b > arr[l_pos] )ans++;
  116. cout<<ans<<'\n';
  117. }
  118.  
  119. }
  120.  
  121. int main(){
  122.  
  123. cin>>t;
  124. while(t--)init();
  125.  
  126. return ;
  127. }

HDU暑假多校第八场J-Taotao Picks Apples的更多相关文章

  1. HDU暑假多校第八场G-Card Game

    一.题意 给出N个卡牌,卡牌的正反两面具有两个数字,取值范围为[1,2*n],给出若干个默认正面向上的卡牌,求最小反转多少张卡牌可以使得,每张卡牌朝上的面上都有一个不同的数字,同时满足最小反转次数的反 ...

  2. HDU暑假多校第四场J-Let Sudoku Rotate

    一.题意 Sudoku is a logic-based, combinatorial number-placement puzzle, which is popular around the wor ...

  3. HDU暑假多校第六场K-werewolf

    一.题意 好人必然说真话,坏人不一定说真话,给定N个人的言论<每人一个发言.不谈及自己>,要求指出有多少个人一定是好人,有多少个人一定是坏人.#define 狼人 坏人#define 村民 ...

  4. HDU暑假多校第三场H.Monster Hunter

    一.题意 给定一个树状地图,每个树节点上有一只怪物,打死一只怪物的过程中将会消耗A点HP,打死之后将会获得B点HP.因为树状结构,所以每只怪物必须先打死父节点的怪兽之后在打死子节点的怪物.现在,给定每 ...

  5. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

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

    牛客多校第3场 J 思维+树状数组+二分 传送门:https://ac.nowcoder.com/acm/contest/883/J 题意: 给你q个询问,和一个队列容量f 询问有两种操作: 0.访问 ...

  7. 2020牛客多校第八场K题

    __int128(例题:2020牛客多校第八场K题) 题意: 有n道菜,第i道菜的利润为\(a_i\),且有\(b_i\)盘.你要按照下列要求给顾客上菜. 1.每位顾客至少有一道菜 2.给顾客上菜时, ...

  8. 2014 HDU多校弟六场J题 【模拟斗地主】

    这是一道5Y的题目 有坑的地方我已在代码中注释好了 QAQ Ps:模拟题还是练的太少了,速度不够快诶 //#pragma comment(linker, "/STACK:16777216&q ...

  9. 2014 HDU多校弟五场J题 【矩阵乘积】

    题意很简单,就是两个大矩阵相乘,然后求乘积. 用 Strassen算法 的话,当N的规模达到100左右就会StackOverFlow了 况且输入的数据范围可达到800,如果变量还不用全局变量的话连内存 ...

随机推荐

  1. ORA-01795: 列表中的最大表达式数为1000的解决方法

    IN中的数据量不能超过1000条. 解决方案:把条件分成多个少于1000的IN即: DELETEFROMT_MM_SECTION_SITE_UPDATEWHERE T.T_MM_SECTION_SL_ ...

  2. libevent evbuffer参考文章

    https://blog.csdn.net/FreeeLinux/article/details/52799951 http://cache.baiducontent.com/c?m=9d78d513 ...

  3. codeforces 676C

    C. Vasya and String time limit per test 1 second memory limit per test 256 megabytes input standard ...

  4. 【转】netstat 命令当中的内部地址和外部地址分别代表的是什么?

    RT,用自己的话解释,不要搬网上的内容.尽量可以简洁,谢谢 2015-03-07 17:41 提问者采纳   网络连接是有2方参与,自己就是“内部地址”,别人就是“外部地址”,就这么简洁. 再举个例子 ...

  5. 【题解】UVA756 Biorhythms (中国剩余定理)

    UVA756:https://www.luogu.org/problemnew/show/UVA756 思路 几乎是裸的中国剩余定理模板题 但是需要注意的是此题并不是求最小正整数解 而是求大于d的解 ...

  6. Angularjs 数据双向绑定

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  7. static函数

    C语言中使用静态函数的好处:      静态函数会被自动分配在一个一直使用的存储区,直到退出应用程序实例,避免了调用函数时压栈出栈,速度快很多.       关键字“static”,译成中文就是“静态 ...

  8. toad for sql server

    数据库连接工具 toad for sql  sever

  9. 关于Mobius反演

    欧拉函数 \(\varphi\) \(\varphi(n)=\)表示不超过 \(n\) 且与 \(n\) 互质的正整数的个数 \[\varphi(n)=n\cdot \prod_{i=1}^{s}(1 ...

  10. ETO的公开赛T1《矿脉开采》题解(另类版)

    这道题别看是签到题,写起来一点不简单 出题人的正解是双向搜索 我们把物品分成两半 每一半分别跑搜索 答案存下来,用个双指针合并即可 然后我构造了两组数据卡掉了他,不得不缩小数据范围 但我这里为什么要致 ...