其实是一道性质题。

首先观察到插入的数是递增的,

那么根据上升子序列的性质,

我们的非法情况就是统计到了在一个数前面的后插入的数,

但是由于插入的数是递增的,显然插入这个数后,这个数就是最大的,所以除了它自己,不会有任何数统计到它,

也就是说,插入一个数时,因为它后面的数都比它小,所以不会对后面DP值产生影响,

而显然它也是不会对它前面的数产生影响的,

因此插入操作实质上是一种无效操作。

所以我们只需要得到最终序列,然后直接dp得到以每个数为结尾的最长上升子序列,

然后统计答案的时候按照数的大小输出前缀max即可。

  1. #include<bits/stdc++.h>
  2. #include<ext/rope>
  3. using namespace std;
  4. using namespace __gnu_cxx;
  5. #define R register int
  6. #define AC 110000
  7. #define getchar() *o++
  8. char READ[],*o=READ;
  9. int n,tot,maxn;
  10. int s[AC],d[AC],ans[AC];
  11. rope <int> tmp;
  12. /*这大概是一道很妙的观察性质题吧,,,
  13. 可以观察到,对于插入任意一个数而言,不管插在哪里,对它前面的DP值是不会产生影响的,
  14. 而由于插入的数是递增的,所以插入这个数时,这个数自己就是当前数列里最大的那一个,
  15. 所以对后面的DP值也不会产生影响,所以其实只需要得到最后的序列直接DP即可以了,因为插入是无效的。
  16.  
  17. 换句话来说,就是因为直接对最后序列查询得到的是不合法结果,当且仅当这个数的DP值中利用到了
  18. 在这个数前面的,且在它后面插入的数。而对于这道题而言,在它后面插入的数都比它大,
  19. 所以插在前面肯定查询不到,而插在后面自然也查不到了,所以直接做就好了
  20.  
  21. 那如何处理输出问题呢?
  22. 因为时间顺序就是数字大小,因此把每个位置的DP值放入对应的数字大小里,然后前缀取max就可以了
  23. */
  24. inline int read()
  25. {
  26. int x=;char c=getchar();
  27. while(c > '' || c < '') c=getchar();
  28. while(c >= '' && c <= '') x=x*+c-'',c=getchar();
  29. return x;
  30. }
  31.  
  32. void pre()
  33. {
  34. n=read();
  35. for(R i=;i<=n;i++)
  36. {
  37. int a=read();
  38. tmp.insert(a,i);
  39. }
  40. //printf("!!!");
  41. for(R i=;i<=n;i++)
  42. {
  43. // printf("%d\n",i);
  44. s[i]=tmp.at(i-);
  45. // if(s[i] == 1) printf("!!!%d\n",i);
  46. }
  47. }
  48.  
  49. void half(int x)
  50. {
  51. int l=,r=tot,mid;
  52. while(l < r)
  53. {
  54. mid=(l + r) >> ;
  55. if(d[mid] > x) r=mid;//因为这里直接转移是保护了信息的,因此寻找第一个大于x的数
  56. else l=mid+;
  57. }
  58. d[l]=x;
  59. ans[x]=l;
  60. }
  61. //这种二分所利用的单调性实质上是因为前面被放入的后面一定可以用?
  62. void work()
  63. {
  64. //for(R i=1;i<=n;i++) printf("%d ",s[i]);
  65. //printf("\n");
  66. for(R i=;i<=n;i++)
  67. {
  68. if(s[i] > d[tot]) d[++tot]=s[i],ans[s[i]]=tot;
  69. else if(s[i] < d[]) d[]=s[i],ans[s[i]]=;//error!!!放入第一个ans当然=1了
  70. else half(s[i]);
  71. //ans[s[i]]=tot;//ans[s[i]]代表放入了s[i]后的最大ans,error 不能在这里就改最大ans,因为会统计到大于s[i]的ans
  72. //error!!!但还是要前缀和取max,因为这个只是统计到了s[i]的ans,还要考虑比s[i]小的数(之前插入)的ans
  73. //因为比s[i]小的数位置可能在右边,这个时候还没有统计到
  74. }//error!!!注意是存入对应的值所在位置
  75. for(R i=;i<=n;i++)
  76. {
  77. maxn=max(maxn,ans[i]);
  78. printf("%d\n",maxn);
  79. }
  80. }
  81.  
  82. int main()
  83. {
  84. // freopen("in.in","r",stdin);
  85. fread(READ,,,stdin);
  86. pre();
  87. work();
  88. // fclose(stdin);
  89. return ;
  90. }

[TJOI2013]最长上升子序列 平衡树的更多相关文章

  1. Bzoj 3173: [Tjoi2013]最长上升子序列 平衡树,Treap,二分,树的序遍历

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1183  Solved: 610[Submit][St ...

  2. bzoj3173[Tjoi2013]最长上升子序列 平衡树+lis

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2253  Solved: 1136[Submit][S ...

  3. BZOJ 3173: [Tjoi2013]最长上升子序列( BST + LIS )

    因为是从1~n插入的, 慢插入的对之前的没有影响, 所以我们可以用平衡树维护, 弄出最后的序列然后跑LIS就OK了 O(nlogn) --------------------------------- ...

  4. BZOJ_3173_[Tjoi2013]最长上升子序列_splay

    BZOJ_3173_[Tjoi2013]最长上升子序列_splay Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数 ...

  5. 【LG4309】【BZOJ3173】[TJOI2013]最长上升子序列

    [LG4309][BZOJ3173][TJOI2013]最长上升子序列 题面 洛谷 BZOJ 题解 插入操作显然用平衡树就行了 然后因为后面的插入对前面的操作无影响 就直接在插入完的序列上用树状数组求 ...

  6. bzoj 3173 [Tjoi2013]最长上升子序列 (treap模拟+lis)

    [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2213  Solved: 1119[Submit][Status] ...

  7. [BZOJ3173][Tjoi2013]最长上升子序列

    [BZOJ3173][Tjoi2013]最长上升子序列 试题描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上 ...

  8. BZOJ 3173: [Tjoi2013]最长上升子序列

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1524  Solved: 797[Submit][St ...

  9. BZOJ 3173: [Tjoi2013]最长上升子序列 [splay DP]

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1613  Solved: 839[Submit][St ...

随机推荐

  1. spring源码-BeanPostProcessor-3.3

    一.BeanPostProcessor这个是spring容器的拓展之一,是用于获取bean的时候处理对应的对象: 二.常用场景,在获取bean的时候,重新初始化bean的属性等. 三.实现方式(加入容 ...

  2. SpringBoot 基于lettuce 连接池 配置redis多数据源操作 生产配置

    添加pom<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons- ...

  3. cf#516B. Equations of Mathematical Magic(二进制,位运算)

    https://blog.csdn.net/zfq17796515982/article/details/83051495 题意:解方程:a-(a^x)-x=0 给出a的值,要求计算解(非负)的个数 ...

  4. hdu1907John(反nim博弈)

    John Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submis ...

  5. Appium Inspector定位元素与录制简单脚本

    本次以微信为例, 使用Appium自带的Inspector定位工具定位元素, 以及进行最最最简单脚本的录制: capabilities = { "platformName": &q ...

  6. Selenium(Python)驱动Firefox浏览器

    我的版本是Firefox Setup 52.7.0.exe+geckodriver-v0.15.0-win64.zip, 把驱动geckodriver.exe放到Python安装目录下, 也可以指定驱 ...

  7. Java应用基础微专业-入门篇

    第1章--用程序来做计算 1.1 第一个Java程序 Mac version: Preference -> General -> Keys -> Search "Conte ...

  8. Java 集合学习--HashMap

    一.HashMap 定义 HashMap 是一个基于散列表(哈希表)实现的键值对集合,每个元素都是key-value对,jdk1.8后,底层数据结构涉及到了数组.链表以及红黑树.目的进一步的优化Has ...

  9. Java学习笔记-13.创建窗口和程序片

    1.init()方法:程序片第一次被创建,初次运行初始化程序片时调用. start()方法:每当程序片进入web浏览器中,并且允许程序片启动他的常规操作时调用(特殊的程序片被stop()关闭):同样在 ...

  10. day-17 L1和L2正则化的tensorflow示例

    机器学习中几乎都可以看到损失函数后面会添加一个额外项,常用的额外项一般有两种,一般英文称作ℓ1-norm和ℓ2-norm,中文称作L1正则化和L2正则化,或者L1范数和L2范数.L2范数也被称为权重衰 ...