Time Limit: 20 Sec  Memory Limit: 128 MB

Submit: 371  Solved: 187

[Submit][Status][Discuss]

Description

佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他。玩具上有一个数列,数列中某些项的值

可能会变化,但同一个时刻最多只有一个值发生变化。现在佳媛姐姐已经研究出了所有变化的可能性,她想请教你
,能否选出一个子序列,使得在任意一种变化中,这个子序列都是不降的?请你告诉她这个子序列的最长长度即可
。注意:每种变化最多只有一个值发生变化。在样例输入1中,所有的变化是:
1 2 3
2 2 3
1 3 3
1 1 31 2 4
选择子序列为原序列,即在任意一种变化中均为不降子序列在样例输入2中,所有的变化是:3 3 33 2 3选择子序列
为第一个元素和第三个元素,或者第二个元素和第三个元素,均可满足要求

Input

输入的第一行有两个正整数n, m,分别表示序列的长度和变化的个数。接下来一行有n个数,表示这个数列原始的

状态。接下来m行,每行有2个数x, y,表示数列的第x项可以变化成y这个值。1 <= x <= n。所有数字均为正整数
,且小于等于100,000

Output

输出一个整数,表示对应的答案

Sample Input

3 4

1 2 3

1 2

2 3

2 1

3 4

Sample Output

3

【题解】

题的意思是说进行一次变化操作之后,变成新的序列,然后序列又变回原状,然后再进行下一个变换,变成新状态->又变回原状。。

然后在这几次变化之后形成的所有序列。找一个下标a1,a2..at,在这所有形成的序列中都都要满足a[a1]<=a[a2]<=...<=a[at].

求t的最大值。

设下标为i的数字最大会变成r[i],最小会变成l[i].然后原数字是v[i]

则第j个元素能接在第i个元素后面加长以第i个元素为结尾的最长上升序列的长度的条件是r[i] <= a[j]且a[i] <= l[j].前者是第i个元素发生变化,后者是第j个元素发生变化所要满足的情况。

还是提醒一句。进行一次操作过后。马上序列又变回原状。而且每次操作只会改变一个对应下标的数字。

则f[j] = max(f[i])+1;(i∈1..j-1;a[i] <= l[j]且r[i] <= a[j])

但是n=10W.

这种做法是n^2的。。

于是做一下改进。

我们在转移的时候实际上就是在找某些范围里面的点。

我们设点的坐标为(a[p],r[q]);(抽象)

那我们对第i个数字进行DP的时候

实际上就是要在某种数据结构中找坐标范围为(0..l[i],0..a[i])的点里面f值最大的。

转移完之后就获得了f[i]的值。

然后再把第i个点的f[i]加到这种数据结构里面就好了。

这种问题可以用kdtree来实现。

n太巨大。需要不时重建kdtree。不然插入操作会让kdtree退化。

经过试验每6000次重建一次效果最好。5000也能通过。

4000、10000这些周期则会T

具体看代码

【代码】

  1. #include <cstdio>
  2. #include <algorithm>
  3.  
  4. using namespace std;
  5.  
  6. const int MAXN = 109000;
  7.  
  8. int n, m,root,ans = 0,now;
  9.  
  10. struct point
  11. {
  12. int l, r,v;
  13. };
  14.  
  15. struct node
  16. {
  17. int ma_x[2], mi_n[2], l, r, dot,f, max,d[2];
  18. };
  19.  
  20. point shuju[MAXN];
  21. node t[MAXN],op;
  22. int totn = 0,mi_n[2],ma_x[2];
  23.  
  24. void input_data()
  25. {
  26. scanf("%d%d", &n, &m);
  27. for (int i = 1; i <= n; i++)
  28. {
  29. scanf("%d", &shuju[i].v);
  30. shuju[i].l = shuju[i].r = shuju[i].v;
  31. }
  32. for (int i = 1; i <= m; i++)
  33. {
  34. int index, num;
  35. scanf("%d%d", &index, &num);
  36. shuju[index].l = min(shuju[index].l, num);
  37. shuju[index].r = max(shuju[index].r, num);
  38. }
  39. }
  40.  
  41. void up_data(int rt)
  42. {
  43. int l = t[rt].l, r = t[rt].r;
  44. for (int i = 0; i <= 1; i++)
  45. {
  46. if (l)
  47. {
  48. t[rt].ma_x[i] = max(t[rt].ma_x[i], t[l].ma_x[i]);
  49. t[rt].mi_n[i] = min(t[rt].mi_n[i], t[l].mi_n[i]);
  50. if (t[l].max > t[rt].max)
  51. {
  52. t[rt].max = t[l].max;
  53. //t[rt].dot = t[l].dot;
  54. }
  55. }
  56. if (r)
  57. {
  58. t[rt].ma_x[i] = max(t[rt].ma_x[i], t[r].ma_x[i]);
  59. t[rt].mi_n[i] = min(t[rt].mi_n[i], t[r].mi_n[i]);
  60. if (t[r].max > t[rt].max)
  61. {
  62. t[rt].max = t[r].max;
  63. //t[rt].dot = t[r].dot;
  64. }
  65. }
  66. }
  67. }
  68.  
  69. void insert(int &rt, int fx)//插入节点
  70. {
  71. if (!rt)
  72. {
  73. rt = ++totn;
  74. t[rt] = op;
  75. t[rt].max = t[rt].f;
  76. t[rt].l = t[rt].r = 0;
  77. //t[rt].dot = rt;
  78. for (int i = 0; i <= 1; i++)
  79. t[rt].ma_x[i] = t[rt].mi_n[i] = t[rt].d[i];
  80. return;
  81. }
  82. else
  83. {
  84. if (op.d[fx] < t[rt].d[fx])
  85. insert(t[rt].l, 1 - fx);
  86. else
  87. insert(t[rt].r, 1 - fx);
  88. }
  89. up_data(rt);
  90. }
  91.  
  92. int query(int rt)
  93. {
  94. if (!rt)
  95. return 0;
  96. if (mi_n[0] <= t[rt].mi_n[0] && t[rt].ma_x[0] <= ma_x[0]
  97. && mi_n[1] <= t[rt].mi_n[1] && t[rt].ma_x[1] <= ma_x[1])
  98. return t[rt].max; //整棵子树里面的点都在所求范围内
  99. if (t[rt].ma_x[0] < mi_n[0] || t[rt].mi_n[0] > ma_x[0] || t[rt].ma_x[1] < mi_n[1]
  100. || t[rt].mi_n[1] > ma_x[1])//都不在范围内
  101. return 0;
  102. int big = 0;
  103. if (mi_n[0] <= t[rt].d[0] && t[rt].d[0] <= ma_x[0] &&
  104. mi_n[1] <= t[rt].d[1] && t[rt].d[1] <= ma_x[1])
  105. big = max(big, t[rt].f);//当前这个节点在范围内。
  106. int l = t[rt].l, r = t[rt].r;
  107. if (l)
  108. big = max(big, query(l));
  109. if (r)
  110. big = max(big, query(r));
  111. return big;
  112. }
  113.  
  114. bool cmp(node a, node b)
  115. {
  116. return a.d[now] < b.d[now];
  117. }
  118.  
  119. int rebuild(int begin, int end, int fx)
  120. {
  121. int m = (begin + end) >> 1;
  122. now = fx;
  123. nth_element(t + begin, t + m, t + end + 1, cmp);
  124. for (int i = 0; i <= 1; i++)
  125. t[m].ma_x[i] = t[m].mi_n[i] = t[m].d[i];
  126. t[m].max = t[m].f;
  127. if (begin < m)
  128. t[m].l = rebuild(begin, m - 1, 1 - fx);
  129. else
  130. t[m].l = 0;//不能省,要重建的
  131. if (m < end)
  132. t[m].r = rebuild(m + 1, end, 1 - fx);
  133. else
  134. t[m].r = 0;
  135. up_data(m);
  136. return m;
  137. }
  138.  
  139. void get_ans()
  140. {
  141. //j < i r[j] <= v[i]
  142. //j < i v[j] <= l[i]
  143. op.d[0] = shuju[1].r;
  144. op.d[1] = shuju[1].v;
  145. op.f = 1;
  146. insert(root,0);
  147. ans = 1;
  148. for (int i = 2;i <= n;i++)
  149. {
  150. if ((i % 6000) == 0)
  151. {
  152. root = rebuild(1, totn,0);
  153. }
  154. mi_n[0] = 0; ma_x[0] = shuju[i].v;
  155. mi_n[1] = 0; ma_x[1] = shuju[i].l;
  156. int temp = query(root);
  157. op.d[0] = shuju[i].r;
  158. op.d[1] = shuju[i].v;
  159. op.f = 1;
  160. if (temp)
  161. {
  162. if (temp + 1 > ans)
  163. ans = temp + 1;
  164. op.f = temp + 1;
  165. }
  166. insert(root, 0);
  167. }
  168. }
  169.  
  170. void output_ans()
  171. {
  172. printf("%d\n", ans);
  173. }
  174.  
  175. int main()
  176. {
  177. //freopen("F:\\rush.txt", "r", stdin);
  178. input_data();
  179. get_ans();
  180. output_ans();
  181. return 0;
  182. }

【50.40%】【BZOJ 4553】[Tjoi2016&Heoi2016]序列的更多相关文章

  1. BZOJ 4553 Tjoi2016&Heoi2016 序列

    Tjoi2016&Heoi2016序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值 可能会变化,但同一个时刻最 ...

  2. BZOJ 4553 [Tjoi2016&Heoi2016]序列 ——CDQ分治 树状数组

    考虑答案的构成,发现是一个有限制条件的偏序问题. 然后三个维度的DP,可以排序.CDQ.树状数组各解决一维. #include <map> #include <cmath> # ...

  3. 4553: [Tjoi2016&Heoi2016]序列

    4553: [Tjoi2016&Heoi2016]序列 链接 分析: 注意所有m此操作中,只会发生一个,于是考虑dp.dp[i]=dp[j]+1,j<i,a[j]<=L[i],R[ ...

  4. [BZOJ4553][TJOI2016&&HEOI2016]序列(CDQ分治)

    4553: [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 554[Su ...

  5. [BZOJ4553][Tjoi2016&Heoi2016]序列 cdp分治+dp

    4553: [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 260  Solved: 133[Sub ...

  6. 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组

    [BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...

  7. bzoj4553 [Tjoi2016&Heoi2016]序列 树状数组(区间最大值)+cqd

    [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1006  Solved: 464[Submit][ ...

  8. BZOJ 4552: [Tjoi2016&Heoi2016]排序

    4552: [Tjoi2016&Heoi2016]排序 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 579  Solved: 322[Sub ...

  9. BZOJ 4554: [Tjoi2016&Heoi2016]游戏 二分图匹配

    4554: [Tjoi2016&Heoi2016]游戏 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4554 Descripti ...

  10. bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二类斯特林数 等比数列求和优化

    [Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 679  Solved: 534[Submit][S ...

随机推荐

  1. iOS 9适配

    iOS 9系统策略更新,请开发者注意升级 近期苹果公司iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查 ...

  2. python 子类中定义init方法

  3. PHPCMS快速建站系列

    模板标签   {pc:content action="position" posid="2" order="id DESC" num=&qu ...

  4. 洛谷P2062 分队问题

      这是一道普及/提高- 然后你懂的,贪心扫一遍就可以了. 不懂提交人数那么少. //Serene #include<algorithm> #include<iostream> ...

  5. 【JZOJ4833】【NOIP2016提高A组集训第3场10.31】Mahjong

    题目描述 解法 搜索. 代码 #include<stdio.h> #include<iostream> #include<string.h> #include< ...

  6. mysql设置text字段为not null,并且没有默认值,插入报错:doesn't have a default value

    一.问题描述 在往数据库写入数据的时候,报错: '字段名' doesn't have a default value 本来这个错误是经常见到的,无非就是字段没有设置默认值造成的.奇怪的是,我这边报错的 ...

  7. 开发者说:Sentinel 流控功能在 SpringMVC/SpringBoot 上的实践

    从用户的视角来感受一个开源项目的成长,是我们推出「开发者说」专栏的初衷,即在开发者进行开源项目选型时,提供更为立体的项目信息.专栏所有内容均来自作者原创/投稿,本文是「开发者说」的第6篇,作者 Jas ...

  8. 1月房地产企业销售TOP100出炉 万科重回第一

    1月房地产企业销售TOP100出炉 万科重回第一 2017-02-05 07:40:32 来源:腾讯新闻 责任编辑: [摘要]TOP100房企1月的销售金额合计4311.8亿元,销售面积合计3648. ...

  9. BKDRhash

     哈希: 字符串(数字同理): 例如有100000个字符串,现在要插入一些字符串,插入前比较是否已经存在避免含有重复数据 用暴力计较的话会比较慢,在某字符串插入时,最好的情况是在第一个位置就遇见该字符 ...

  10. selenium webdriver学习(九)------------如何操作cookies(转)

    selenium webdriver学习(九)------------如何操作cookies 博客分类: Selenium-webdriver   Web 测试中我们经常会接触到Cookies,一个C ...