zoukankan      html  css  js  c++  java
  • [杂题]URAL2047. Maths

    题意:构造一个长度为n的串,使得 除了第一个以外,每个位置的前缀和的因子个数恰好等于该位置上的数。

    n$le 100000$

    举个例子$a_i$:2   4    6     6    4    8    4    8    4   8

        前缀和   :     6   12   18   22  30  34  42  46  54

    6的因子:1 2 3 6 为4个  等于a[2]

    12的因子:1 2 3 4 6 12 为6个  等于a[3]

    18的因子:1 2 3 6 9 18 为6个  等于a[4]

    ...

    ...

    54的因子:1 2 3 6 9 18 27 54 为8个 等于a[9]

    所有都满足,则该列合法

    一开始一直在想到哪儿为止会Impossible

    然后就打算暴力一发 看到哪儿为止

    后来发现正着写,根本写不出来。

    于是发现把每个数的因子数写出来,倒着减回去,

    每个数回去都只有一条路,最长的就是答案。

    比如

    27这个数回去 长度为9

    26这个数回去 长度为6

    ...

    每个数回去都有一个长度

    后来发现只需知道 “那个数减去因子个数” 的 那个数 回去有多长+1就好啦

    那只要预处理一下因子个数

    正着for一遍,O(1)就能得到长度

    (for的是 和 , 长度就是题目输入的n , 需要输出的是 长度最长的那一串回去的路上的数的因子数)

    那么打个这样的表,只需1秒钟

    int phi[20000005];
    int pri()
    {
        memset(phi, 0, sizeof(phi));
        for(int i=2;i<=2000000;i++)
            for(int j=i;j<=2000000;j+=i)
                phi[j]++;
    }
    
    int dp[20000005];
    void pre()
    {
        memset(dp, 0, sizeof(dp));
        dp[1]=1, dp[2]=1;
        for(int i=3;i<=2000000;i++)
        {
            int num=phi[i]+1;
    //        if(num>300 || dp[i-num]==-1)
    //            dp[i]=-1;
    //        else
                dp[i]=dp[i-num]+1;
    //        printf("%d %d
    ", i, dp[i]);
            if(dp[i]>=100000)
            {
                printf("%d %d
    ", i, dp[i]);
                break;
            }
        }
    }
    
    int main()
    {
    //    freopen("out.txt", "w", stdout);
        pri();
        pre();
        return 0;
    }

    得到的这个1568617就是n为100000的最后一个数

    要得到n个数,倒着减回去就好了

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 typedef pair<int, int> PI;
     5 const int N=1e5+5;
     6 const double eps=1e-5;
     7 const int mod=1e9+7;
     8 
     9 int ans[100005], d;
    10 int phi[1568625];
    11 void pre()
    12 {
    13     memset(phi, 0, sizeof(phi));
    14     for(int i=2;i<=1568617;i++)
    15         for(int j=i;j<=1568617;j+=i)
    16             phi[j]++;
    17     int x=1568617;
    18     d=0;
    19     while(x)
    20     {
    21         ans[d++]=x;
    22         int num=phi[x]+1;
    23         x-=num;
    24     }
    25 }
    26 
    27 int main()
    28 {
    29     pre();
    30     int n;
    31     while(~scanf("%d",&n))
    32     {
    33         int sum=0;
    34         for(int i=d-1, j=1;j<=n;j++, i--)
    35         {
    36             printf("%d", ans[i]-sum);
    37             sum=ans[i];
    38             if(j==n)
    39                 puts("");
    40             else
    41                 putchar(' ');
    42         }
    43     }
    44     return 0;
    45 }
    Ural 2047
  • 相关阅读:
    PHP入门
    requests中text,content,json之间的区别
    有关pip报错的问题

    pycharm操作
    python selenium 相关操作
    python tkinter菜单
    初识Go
    Python _easygui详细版
    easygui _1
  • 原文地址:https://www.cnblogs.com/Empress/p/4866207.html
Copyright © 2011-2022 走看看