• codeforces546D(从一个数中拆分素数)


    D. Soldier and Number Game
    time limit per test
    3 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Two soldiers are playing a game. At the beginning first of them chooses a positive integer n and gives it to the second soldier. Then the second one tries to make maximum possible number of rounds. Each round consists of choosing a positive integer x > 1, such that n is divisible by x and replacing n withn / x. When n becomes equal to 1 and there is no more possible valid moves the game is over and the score of the second soldier is equal to the number of rounds he performed.

    To make the game more interesting, first soldier chooses n of form a! / b! for some positive integer a and b (a ≥ b). Here by k! we denote the factorial of k that is defined as a product of all positive integers not large than k.

    What is the maximum possible score of the second soldier?

    Input

    First line of input consists of single integer t (1 ≤ t ≤ 1 000 000) denoting number of games soldiers play.

    Then follow t lines, each contains pair of integers a and b (1 ≤ b ≤ a ≤ 5 000 000) defining the value ofn for a game.

    Output

    For each game output a maximum score that the second soldier can get.

    Examples
    Input
    2
    3 1
    6 3
    
    Output
    2
    5

    题目大意:

    一开始N是a!/b!.每一次士兵选择一个数x,使得n变成n/x.

    他希望玩游戏的轮数尽可能的多,问给出的N最多可以玩几轮。

    思路:

    给出的Na!/b!,其中保证a>=b.那么我们的N其实就是从b+1~a之间所有数去拆分素因子的问题。

    那么我们处理出从2~5e6这些数都可以拆分出来多少素因子然后维护一个前缀和即可。

    代码:

    #include<stdio.h>
    #include<string.h>
    int s[5000050],vt[5000050];
    int init()
    {
      int i,j;
      memset(s,0,sizeof(s));
      memset(vt,0,sizeof(vt));
      for(i=2;i<=5000005;i++)// 乍一看这代码时间复杂度很高,但是细想一下代码运行次数只有2*5000000次数左右,但是我们的vt数组就将我们时间复杂度降了下来,避免了不必要的计算
      {
        if(!vt[i])//判断i是不是素数
        {
          for(j=i;j<=5000005;j+=i)//对于一个素数,只有它的倍数才能被他整除 ,节省时间
          {
            int a=j;
            while(a%i==0)//对j进行拆分
            {
              s[j]++;
              a=a/i;
            }
            vt[j]=1;//j已经经历过了或者j不是素数
          }
        }
      }
      for(i=2;i<=5000001;i++)
      s[i]=s[i-1]+s[i];
    }
    int main()
    {
      init();
      int a,b,t;
      scanf("%d",&t);
      while(t--)
      {
        scanf("%d%d",&a,&b);
        printf("%d ",s[a]-s[b]);
      }
        return 0;
    }

     乍一看这代码时间复杂度很高,但是细想一下代码运行次数只有2*5000000次数左右,

  • 相关阅读:
    CF EDU
    Educational Codeforces Round 48 D Vasya And The Matrix
    牛客2018多校第五场E-room 最小费用最大流
    数据结构:分块-区间加法、区间乘法和单点查询
    数据结构:分块-单点插入和单点询问
    数据结构:分块-区间开方与区间求和
    数据结构:分块-区间加法与区间求和
    数据结构:分块-区间加法和查询前驱(比其小的最大元素)
    数据结构:分块-区间加法和询问小于指定元素的个数
    数据结构:分块-区间加法和点查询
  • 原文地址:https://www.cnblogs.com/cglongge/p/8893701.html
Copyright © 2020-2023  润新知