zoukankan      html  css  js  c++  java
  • [HNOI2002]跳蚤

    题目描述

    Z城市居住着很多只跳蚤。在Z城市周六生活频道有一个娱乐节目。一只跳蚤将被请上一个高空钢丝的正中央。钢丝很长,可以看作是无限长。节目主持人会给该跳蚤发一张卡片。卡片上写有N+1个自然数。其中最后一个是M,而前N个数都不超过M,卡片上允许有相同的数字。跳蚤每次可以从卡片上任意选择一个自然数S,然后向左,或向右跳S个单位长度。而他最终的任务是跳到距离他左边一个单位长度的地方,并捡起位于那里的礼物。

    比如当N=2,M=18时,持有卡片(10, 15, 18)的跳蚤,就可以完成任务:他可以先向左跳10个单位长度,然后再连向左跳3次,每次15个单位长度,最后再向右连跳3次,每次18个单位长度。而持有卡片(12, 15, 18)的跳蚤,则怎么也不可能跳到距他左边一个单位长度的地方。

    当确定N和M后,显然一共有MN张不同的卡片。现在的问题是,在这所有的卡片中,有多少张可以完成任务。

    输入输出格式

    输入格式:

    输入文件有且仅有一行,包括用空格分开的两个整数N和M。

    输出格式:

    输出文件有且仅有一行,即可以完成任务的卡片数。

    1≤M≤108,1≤N≤M,且MN≤1016。

    输入输出样例

    输入样例#1:
    2  4
    输出样例#1:
    12

    说明

    这12张卡片分别是:

    (1, 1, 4), (1, 2, 4), (1, 3, 4), (1, 4, 4), (2, 1, 4), (2, 3, 4),

    (3, 1, 4), (3, 2, 4), (3, 3, 4), (3, 4, 4), (4, 1, 4), (4, 3, 4)

    题解:

    可以说

    a1*1+a2*2+a3*3.....+am*m=1有解的方案数

    就是GCD(a1,a2,...,am)=1

    所以肯定有很多a=0,不为0的最多有n+1个

    总方案就是m^n,由容斥原理

    先将含有n个1个素数因子的数的方案数减去,再加去n个含有2个素数因子的方案,再减去3个,加上4个的方案。

    直到cnt个(素数因子的数量)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 typedef long long lol;
     7 lol n,m,ans;
     8 int cnt,prime[1000001];
     9 lol pow(lol x,lol y)
    10 {
    11     lol res=1;
    12     while (y)
    13     {
    14         if (y%2==1)
    15         res*=x;
    16         x*=x;
    17         y/=2;
    18     }
    19     return res;
    20 }
    21 void dfs(lol goal,lol x,lol c,lol num)
    22 {
    23     
    24     if (num>goal)
    25     {
    26         if (goal%2==1)
    27         ans-=pow(m/c,n);
    28         else ans+=pow(m/c,n);
    29         return;
    30     
    31     }if (x>cnt) return;
    32     dfs(goal,x+1,c*prime[x],num+1);
    33     dfs(goal,x+1,c,num);
    34 }
    35 int main()
    36 {int i;
    37     cin>>n>>m;
    38     if (m==0)
    39     {
    40         cout<<0;
    41         return 0;
    42     }
    43      ans=pow(m,n);
    44      lol x=m;
    45      for (i=2;i*i<=x;i++)
    46      {
    47          if (x%i==0)
    48          {
    49              cnt++;
    50              prime[cnt]=i;
    51              while (x%i==0) x/=i;
    52         }    
    53      }
    54      if (x-1) 
    55         {
    56             cnt++;
    57             prime[cnt]=x;
    58         }
    59      for (i=1;i<=cnt;i++)
    60      {
    61           dfs(i,1,1,1);
    62      }
    63     cout<<ans;
    64 }
  • 相关阅读:
    Codevs2822 爱在心中
    3098: Hash Killer II
    课程总结
    团队作业——个人总结
    团队作业2
    团队个人分工
    装甲车团队介绍(别急,在做了)
    面向对象程序设计作业(4)
    面向对象程序设计作业(3)
    面向对象程序设计(2)
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7236578.html
Copyright © 2011-2022 走看看