zoukankan      html  css  js  c++  java
  • Codeforces 448 E. Divisors (DFS,储存结构)

    题目链接:E. Divisors

    题意:

      给出一个X,f(X)是X所有约数的数列(例6:1 2 3 6),给出一个k,k是递归的次数(例:k=2 : f(f(X)) ; X=4,k=2: 1 1 2 1 2 4 ), X (1 ≤ X ≤ 10^12) and k (0 ≤ k ≤ 10^18)。现在给出X与k让你求这个序列,序列长度如果超过1e5就只存1e5个数。

    题解:

      这个题的话除了DFS没有想到特别好的方法,但是问题是强行DFS时间会超@。@。(DFS思路:处理出dfs时数的所有约数(n^1/2)最大是1e6的复杂度。深度最大是1e5:深度大于1e5其实就可以特判:如果N是1输出1,不然就输出1e5个1)。但是这样我们发现每次dfs都有处理约数复杂度太大,我们可以用map储存vector的方式。如果这个数以前已经被处理过就直接用,没处理过就处理后放到vector中再丢到map里面。(一定要用vector,在dfs中用静态数组好像很容易爆空间@。@)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAX_N = 3e5+9;
     4 vector<long long> vec;
     5 long long out[MAX_N];
     6 int num = 0;
     7 long long N,M,T;
     8 map< long long , vector<long long> > mp;
     9 void dfs(long long n,int pos)
    10 {
    11     if(num>=1e5) return;
    12     vector <long long> vec;
    13     if(mp.count(n)) vec = mp[n];
    14     else
    15     {
    16         // vector 初始化
    17         for(long long i=1;i*i<=n;i++)
    18         {
    19             if(n%i==0)
    20             {
    21                 vec.push_back(i);
    22                 if(i != n/i) vec.push_back(n/i);
    23             }
    24         }
    25         sort(vec.begin(),vec.end());
    26         mp.insert(make_pair(n,vec));
    27     }
    28     if(pos == M)
    29     {
    30         for(int i=0;i<vec.size();i++)
    31         {
    32             out[num++] = vec[i];
    33             if(num>=1e5) break;
    34         }
    35         return;
    36     }
    37     for(int i=0;i<vec.size();i++)
    38     {
    39         if(vec[i] == 1) out[num++] = 1;
    40         else dfs(vec[i],pos+1);
    41     }
    42 }
    43 int main()
    44 {
    45     while(cin>>N>>M)
    46     {
    47         mp.clear();
    48         if(M==0)
    49         {
    50             printf("%lld
    ",N);
    51             continue;
    52         }
    53         num = 0;
    54 
    55         if(M>=1e5)
    56         {
    57             if(N==1)
    58                 printf("%lld
    ",N);
    59             else
    60                 for(int i=0;i<1e5;i++) printf("1 ");
    61             continue;
    62         }
    63 
    64         dfs(N,1);
    65         for(int i=0;i<num;i++)
    66         {
    67             printf("%lld ",out[i]);
    68         }
    69         printf("
    ");
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    第九届蓝桥杯B组决赛-调手表
    第九届蓝桥杯B组决赛-搭积木
    洛谷P2680(树上差分+二分)
    线段树+扫描线+离散化
    hdu3911(线段树区间异或+区间和并+查询最区间大连续1的个数)
    线段树与位运算
    计蒜客Distance on the tree(主席树+LCA)
    洛谷P4742(tarjan缩点+拓扑DP)
    出题人的手环
    SP263 PERIOD
  • 原文地址:https://www.cnblogs.com/doggod/p/8349429.html
Copyright © 2011-2022 走看看