数论 - 组合数学 + 素数分解 --- hdu 2284 : Solve the puzzle, Save the world!

Solve the puzzle, Save the world!

Problem Description

In the popular TV series Heroes, there is a tagline "Save the cheerleader, Save the world!". Here Heroes continues, "Solve the puzzle, Save the world!".
Finally, alien invaders visit our planet. They are eccentric and launch attack many rounds. Since trust in prime numbers, each round they send out p killers, here p is a prime number. Countries on our planet unite and assemble an armed troop of n population. And fortunately we get a fatal weakness of enemy from a betrayer. If the ways of choosing m warriors from n is a multiple of p, the killer number, we will win. Otherwise, we will lose. As the greatest programmer of our planet, you are invited to write a program to count the number of m(0≤m≤n) such that C(n, m) is a multiple of prime p.

Input

Each line will contain an integer n(1≤n≤10^5) and a prime p(2≤p<10^7), separated by a single space. Process to the end of file.

Output

For each test of case, if the world can be saved, output the number of ways, otherwise, output "Where is hero from?"(without quotation), both on a single line.

Sample Input

6 2
5333 127
100000 11

Sample Output

3
Where is hero from?
92301



Mean:

给你两个数n和p,现在要你从n中选出m个数,如果n取m能够被p整除,那么为可行方案,问可行方案数有多少种。

analyse:

如果数据小的话确实是道水题,当然只要想到这个方法,一样也是水题。

如果我们用传统的方法:枚举m,然后求c(n,m),再看能不能被p整除这样暴力来做的话,光是c(n,m)就存不下,更别提判断整除了。

这题用了一个巧妙的方法,由于题目说p是一个素数,那么我们可直接来统计c(n,m)分子分母的素因子,然后相减之后就是c(n,m)的p因子了。

Time complexity:O(n)

Source code:

// Memory   Time
// 1347K     0MS
// by : Snarl_jsb
// 2014-09-09-20.25
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<string>
#include<climits>
#include<cmath>
#define N 1000010
#define LL long long
using namespace std;

int main()
{
//    freopen("C:\\Users\\ASUS\\Desktop\\cin.cpp","r",stdin);
//    freopen("C:\\Users\\ASUS\\Desktop\\cout.cpp","w",stdout);
    long long n,p;
    while(~scanf("%I64d %I64d",&n,&p))
    {
        if(!n||p>n)
        {
            puts("Where is hero from?");
            continue;
        }
        long long tmp,cnt,m,ans;
        ans=cnt=0;
        for(m=1;m<=n/2;m++)
        {
            tmp=n-m+1;
            while(!(tmp%p))
            {
                cnt++;
                tmp/=p;
            }
            tmp=m;
            while(!(tmp%p))
            {
                cnt--;
                tmp/=p;
            }
            if(cnt<=0)
                continue;
            if(m*2==n)
                ans++;
            else ans+=2;
        }
        if(ans)
            cout<<ans<<endl;
        else puts("Where is hero from?");
    }
    return 0;
}

  

时间: 2024-08-05 19:30:07

数论 - 组合数学 + 素数分解 --- hdu 2284 : Solve the puzzle, Save the world!的相关文章

校队训练赛,同时也是HDU4497(数论:素数分解+组合数学)

一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=4497 二.思路 将满足条件的一组x,z,y都除以G,得到x‘,y',z',满足条件gcd(x',y',x') = 1,同时lcm(x',y',x') = G/L.特判,当G%L != 0 时,无解.然后素数分解G/L,假设G/L = p1^t1 * p2^t2 *````* pn^tn.满足上面条件的x,y,z一定为这样的形式.x' = p1^i1 * p2^i2 *```* pn^in.y' =

HDU4497 GCD and LCM 数论 素数分解

题意很简单首先以前做最简单的LCM跟CGD的时候都知道先求出两个数A,B的最大公约数GCD,那么LCM可以利用  A*B/GCD来求得,这点一开始脑残了没想到,结果没有进行特盘所以错了,意思就是 题目给的L%G不为0的话就是无解,结果我给判其它的去了,肯定漏了些什么没有发现 然后对于 L/G进行素因子分解,同时任意的数都能够通过素因子分解来表示,所以三个解x,y,z也能分解 L/G = p1^q1*p2^q2.... x = p1^i1*... y = p1^j1*... z = p1^k1*.

poj3993Not So Flat After All(筛法素数+分解质因子)

题目链接: 啊哈哈,点我点我 题意: 题意是给出两个数字,然后有由一分解定理得,每个数可以分解成若干质因数的乘积,这样就可以在一个n维的坐标系下表示出这个点...比如给出50和24 因为24=2^3*3^1*5^0  而50=2^1*3^0*5^2那么这两个点就可以在一个3维德坐标系下表示出这两个点..24=(3,1,0)  50=(1,0,2)  那么共同拥有的维度就是3  而两个点在n维坐标系下的距离就是|3-1|+|1-0|+|0-2|=5,这样题意完全理解... 思路: 先筛出10000

hdu 5323 Solve this interesting problem(dfs)

题目链接:hdu 5323 Solve this interesting problem 逆向思维,每次向左或向右翻倍,知道左端点为0时,即恰好满足的情况,处理处所有情况去取最小值. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const ll inf = 0x3f3f3f3f; ll L, R, N; void

Codeforces 223APartial Sums 数论+组合数学

题意很简单,求不是那么好求的,k很大 要操作很多次,所以不可能直接来的,印象中解决操作比较多无非线段树 循环节 矩阵 组合数等等吧,这道题目 也就只能多画画什么 的了 就以第一个案例为主吧 , 3 1 2 3 k我们依据画的次数来自己定好了 下面的每个数表示这个位置的 数由最初的 数组num[]中多少个数加起来得到的 当k为0的时候呢,就是 1 1 1 k为1的时候呢 1 2 3 k为2的时候呢 1 3 6 那么k为3的时候 1 4 10 这里看一下 从数组下标0开始,那么其实就是 C(i +

组合数学+整数分解 POJ 2992 Divisors

题意:给n,k,求C(n,k)的约数的个数. 由于C(n,k)=n!/(k!*(n-k)!),所以只要分别把分子分母的素因子的次数求出来,再用分子的每个素因子的次数减去分母的每个素因子的次数就可以得到C(n,k)的素数分解式,约数个数就等于(p1+1)(p2+1)*...*(pn+1).这道题n,k的范围都是四百多,按理说O(N^2)的算法可以过的,但是测试数据太多了,暴力的方法会TLE.看别人的报告知道了求N!的某个素因子次数的递归算法,然后枚举每个素数,求出它在阶乘中的次数,就可以AC了.

HDU - 1098 - Ignatius&#39;s puzzle (数论 - 费马小定理)

Ignatius's puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7012    Accepted Submission(s): 4847 Problem Description Ignatius is poor at math,he falls across a puzzle problem,so he has no

算法15---数论6---素数,回文素数 分解质因素

算法15---数论6---素数,回文素数  分解质因素 1 /* 2 题目:素数,回文素数 3 author taoliu——alex 2016.10 number4 4 5 主要实现: 6 判断素数,判断回文素数 7 */ 8 9 10 11 #include <stdio.h> 12 #include <math.h> 13 14 15 16 //素数 17 18 19 int isprime(int a) 20 { 21 for (int i = 2; i < a; i

light_oj 1220 素数分解

light_oj 1220  素数分解 J - Mysterious Bacteria Time Limit:500MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Submit Status Practice LightOJ 1220 Description Dr. Mob has just discovered a Deathly Bacteria. He named it RC-01. RC-01 has a very