小 Y 酷爱的接龙游戏正是这样。玩腻了成语接龙之后,小 Y 决定尝试无平方因子二元合数接龙,规则如下:

现有 \(n\) 个不超过 \(K\) 的合数,每个合数 \(a\) 均可表示为 \(a=pq(p \lt q)\)。

若 \(a=p_1q_1(p_1<q_1),b=p_2q_2(p_2<q_2)\),当且仅当 \(q_1=p_2\) 时 \(b\) 能接在 \(a\) 后面。

请问从给定的这 \(n\) 个数中选数接龙,最长可以形成一个包含多少数的接龙序列?

\(1 \le n \le 50000,1 \le K \le 10^6\)

签到题(可我却签了 \(1\) 个小时的到)

首先,我们可以用线性筛做到 \(O(K\log{K})\) 的时间复杂度内分解 \(2 \sim K\) 的所有满足 \(a=pq\) 的数以及它们的 \(p,q\)。

暴力的做法是我们排序,然后当遍历到了 \(i\),就查找所有 \(j\),使得 \(p_j=q_i\)。然后暴力统计。时间复杂度不会算。

然后发现查找 \(j\) 可以先查找第一个 \(j\) 然后二分做到 \(O(\log n)\)。

然后发现查找 \(j\) 可以预处理做到 \(O(1)\)。

如果你真这么写,也许只有 \(60\) 分。

最后我们发现,暴力时我们搜索了许多重复子问题,而重复子问题可以使用动态规划进行优化,这里直接写的是记忆化搜索。

然后就有了一个 \(100\) 分算法。

  1. #include <bits/stdc++.h>
  2. #define int unsigned long long
  3. using namespace std;
  4. const int VSIZE = 1e6+5,N = 50005;
  5. bool vis[VSIZE];
  6. int prime[VSIZE],tot;
  7. int n;
  8. pair<int,int> cj[VSIZE];
  9. int first[VSIZE];
  10. void sieve(){
  11. for(int i=2;i<=1e6;i++){
  12. if(!vis[i]){
  13. prime[++tot]=i;
  14. }
  15. for(int j=1;j<=tot&&i*prime[j]<=1e6;j++){
  16. vis[i*prime[j]]=1;
  17. if(!(i%prime[j])){
  18. break;
  19. }
  20. }
  21. }
  22. for(int i=1;i<=tot;i++){
  23. for(int j=i;j<=tot&&prime[i]*prime[j]<=1e6;j++){
  24. cj[prime[i]*prime[j]].first=(prime[i]);
  25. cj[prime[i]*prime[j]].second=(prime[j]);
  26. }
  27. }
  28. }
  29. pair<int,int> chai(int x){
  30. return cj[x];
  31. }
  32. pair<int,int> a[N];
  33. int nowt;
  34. vector<pair<int,int> > now;
  35. bool visited[N];
  36. int ans;
  37. int f[N];
  38. int dfs(int i){
  39. visited[i]=1;
  40. if(f[i]){
  41. return f[i];
  42. }
  43. f[i]=1;
  44. int second = a[i].second;
  45. int l = first[second];
  46. if(l>0){
  47. for(int j=l;a[j].first==second;j++){
  48. if(a[j].first!=second){
  49. break;
  50. }
  51. f[i]=max(f[i],dfs(j)+1);
  52. }
  53. }
  54. return f[i];
  55. }
  56. signed main(){
  57. ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  58. sieve();
  59. cin>>n;
  60. memset(first,-1,sizeof(first));
  61. for(int i=1;i<=n;i++){
  62. int v;
  63. cin>>v;
  64. a[i]=chai(v);
  65. if(a[i].first>a[i].second){
  66. swap(a[i].first,a[i].second);
  67. }
  68. }
  69. sort(a+1,a+n+1);
  70. for(int i=1;i<=n;i++){
  71. if(first[a[i].first]!=-1){
  72. first[a[i].first]=min(first[a[i].first],i);
  73. }
  74. else{
  75. first[a[i].first]=i;
  76. }
  77. }
  78. for(int i=1;i<=n;i++){
  79. if(!visited[i])
  80. dfs(i);
  81. }
  82. cout<<*max_element(f+1,f+n+1)<<'\n';
  83. return 0;
  84. }

51NOD5213A 【提高组/高分-省选预科 第一场【M】】序列的更多相关文章

  1. 校省选赛第一场A题Cinema题解

    今天是学校省选的第一场比赛,0战绩收工,死死啃着A题来做,偏偏一直WA在TES1. 赛后,才发现,原来要freopen("input.txt","r",stdi ...

  2. 「CSP」第一届提高组考后总结

    「CSP」第一届提高组考后总结 问题分析+反思 成绩 心态 考前心态 考时心态 考后心态 方法 心灵鸡汤... 在学习了三年之后,我们信竞迎来了初中最后一次大考,也是第一次 CSPCSPCSP 考试. ...

  3. 【佛山市选2013】JZOJ2020年8月7日提高组T2 树环转换

    [佛山市选2013]JZOJ2020年8月7日提高组T2 树环转换 题目 描述 给定一棵N个节点的树,去掉这棵树的一条边需要消耗值1,为这个图的两个点加上一条边也需要消耗值1.树的节点编号从1开始.在 ...

  4. 计蒜客 NOIP 提高组模拟竞赛第一试 补记

    计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...

  5. 【佛山市选2013】JZOJ2020年8月7日提高组T3 海明距离

    [佛山市选2013]JZOJ2020年8月7日提高组T3 海明距离 题目 描述 对于二进制串a,b,他们之间的海明距离是指两个串异或之后串中1的个数.异或的规则为: 0 XOR 0 = 0 1 XOR ...

  6. 【佛山市选2013】JZOJ2020年8月7日提高组T1 回文子序列

    [佛山市选2013]JZOJ2020年8月7日提高组T1 回文子序列 题目 描述 回文序列是指左右对称的序列.例如1 2 3 2 1是回文序列,但是1 2 3 2 2就不是.我们会给定一个N×M的矩阵 ...

  7. 比赛总结——牛客网 NOIP赛前集训营提高组模拟第一场

    第一场打的很惨淡啊 t1二分+前缀最小值没想出来,20分的暴力也挂了,只有10分 t2数位dp,调了半天,结果因为忘了判0的特殊情况WA了一个点,亏死 t3emmmm.. 不会 imone说是DSU ...

  8. [NOIP2012] 提高组 洛谷P1081 开车旅行

    题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的 城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 Hi,城市 ...

  9. NOIP2014提高组 酱油记

    NOIP考到哪里我就写到哪里好了. 2014/10/12 初赛 下午两点半开始考,我两点就到了.然后看到了QYL,NYZ,CZR等大神,先Orz了再说. 考试开始前,发现考场竟然没几个我认识的,不是按 ...

  10. NOIP2011提高组 聪明的质监员 -SilverN

    题目描述 小T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 n 个矿石,从 1到n 逐一编号,每个矿石都有自己的重量 wi 以及价值vi .检验矿产的流程是: 1 .给定m 个区间[L ...

随机推荐

  1. JVM中的堆

    堆 内存结构 堆的核心概念 <java虚拟机规范>中对java堆的描述是:所有的对象实例以及数组都应当在运行时分配在堆上. 一个JVM实例只存在一个堆内存(就是new 出来一个对象),ja ...

  2. 不妨试试更快更小更灵活Java开发框架Solon

    @ 目录 概述 定义 性能 架构 实战 Solon Web示例 Solon Mybatis-Plus示例 Solon WebSocket示例 Solon Remoting RPC示例 Solon Cl ...

  3. python的微积分运算

    import sympy sympy.init_printing() from sympy import I, pi, oo import numpy as np 求函数的导数 x = sympy.S ...

  4. python dir函数解析

    dir() 函数  不带参数,直接执行是返回当前环境中对象的名称列表.指定对象的名称作为参数执行,返回指定对象当中的属性(包括函数名,类名,变量名等)   下面我们具体找几个例子测试一下  dir() ...

  5. 《吐血整理》高级系列教程-吃透Fiddler抓包教程(31)-Fiddler如何抓取Android系统中Flutter应用程序的包

    1.简介 Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面.Flutter应用程序是用Dart编写的,这是一种由Google在7年多前创建的语言.Flut ...

  6. JavaScript的异步编程之Promise

    Promise 一种更优的异步编程统一 方法,如果直接使用传统的回调函数去完成复杂操作就会形成回调深渊 // 回调深渊 $.get('/url1'() => { $.get('/url2'() ...

  7. Java多线程(6):锁与AQS(下)

    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 之前说过,AQS(抽象队列同步器)是Java锁机制的底层实现.既然它这么优秀,是骡子是马,就拉出来溜溜吧. 首先用重入锁来实现简单的累加,就像这 ...

  8. ubuntu基本

    ubuntu使用过程中遇到的指令 apt-get更新 当现出net-tools没有可安装候选 的提示时,可能是apt-get需要更新了.通过指令sudo apt install net-tools p ...

  9. Excel表格复制填写

    =if(A1<>"",A1,"") #A1可以为任意表格单元

  10. nydusd 源码理解(一)

    " 尝试通过 nydus[1] 源码理解工作流程.可能由于代码变动导致和本文记录的内容有出入. 1. 环境准备 git clone https://github.com/dragonflyo ...