【n!素因子p的幂】swjtuOJ 2090

【n!素因子p的幂】swjtuOJ 2090

【注:交大的看到这篇文章要学会自己写,不要为了比赛而比赛!~】

题目大意

数论一道好题:给以两个大整数n,s(n<=10^18,s<=10^12),试找到最大的整数k使得n! % s^k ==0

数论一道不错的题目,很容易想到思路,但是数据会大一点,有可能爆long long ,笔者由于n!素因子p的幂采用累乘法,在10^12左右的一个素数爆掉了,QAQ

所以还是用累除法来的稳妥!



说一下思路

  • (1)首先对S进行素因子分解,复杂度O(logN),用map存储,得到所有素因子以及素因子的幂
  • (2)对于每一个素因子p,计算对应的n!中素因子p的幂(复杂度O(logn)),两者相除取所有p幂的最小值就是对应的最大整数k,总的时间复杂度为O(logs·logn)

?求n!素因子p的幂要用累除法呀( ⊙ o ⊙ )!


参考代码

/*====================================*|*        n!素因子p的幂(累除法)     *|
\*====================================*/
/*Author:Hacker_vision*/
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<map>
#include<climits>
#define clr(k,v) memset(k,v,sizeof(k))
#define ll long long
#define eps 1e-8
using namespace  std;

const int _max = 1e3 + 10;
ll n,s,t;
map<ll,int>mp;
map<ll,int>::iterator it;

void divide(ll n){//素因子分解
  mp.clear();
  t = 0;
  for(ll i = 2; i * i <= n; ++ i){
    if(n%i==0){
        mp[i]++;
        n/=i;
        while(n%i==0){
            mp[i]++;
            n/=i;
        }
    }
  }
  if(n!=1) mp[n]++;
}

ll judge(ll p){//n!素因子分解素数p的幂,累除法
  ll cnt= 0;
  ll now = n;
  while(now){
    cnt += now/p;
    now/=p;
  }
  return cnt;
}

ll solve(){
   ll ans = 9223372036854775807ll;
   for(it= mp.begin();it!=mp.end();++it){
      ans = min(judge(it->first)/it->second,ans);
   }
   return ans;
}

int main(){
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);
  #endif // ONLINE_JUDGE
  int T;cin>>T;
  while(T--){
    scanf("%lld%lld",&n,&s);
    divide(s);
    printf("%lld\n",solve());
  }
  return 0;
}

  • 加粗 Ctrl + B
  • 斜体 Ctrl + I
  • 引用 Ctrl + Q
  • 插入链接 Ctrl + L
  • 插入代码 Ctrl + K
  • 插入图片 Ctrl + G
  • 提升标题 Ctrl + H
  • 有序列表 Ctrl + O
  • 无序列表 Ctrl + U
  • 横线 Ctrl + R
  • 撤销 Ctrl + Z
  • 重做 Ctrl + Y

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-14 19:53:44

【n!素因子p的幂】swjtuOJ 2090的相关文章

NEFU 118 n!后面有多少个0 (n!的素因子幂问题)

n!后面有多少个0 Problem : 118 Time Limit : 1000ms Memory Limit : 65536K description 从输入中读取一个数n,求出n!中末尾0的个数. input 输入有若干行.第一行上有一个整数m,指明接下来的数字的个数.然后是m行,每一行包含一个确定的正整数n,1<=n<=1000000000. output 对输入行中的每一个数据n,输出一行,其内容是n!中末尾0的个数. sample_input 3 3 100 1024 sample

UVa10780

10780 Again Prime? No time.The problem statement is very easy. Given a number n you have to determine the largest power of m,not necessarily prime, that divides n!.InputThe input file consists of several test cases. The first line in the file is the

hdu-5833 Zhu and 772002(高斯消元)

题目链接: Zhu and 772002 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1006    Accepted Submission(s): 348 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test the

Codeforces Round #319 (Div. 2) C Vasya and Petya&#39;s Game

因为所有整数都能被唯一分解,p1^a1*p2^a2*...*pi^ai,而一次询问的数可以分解为p1^a1k*p2^a2k*...*pi^aik,这次询问会把所有a1>=a1k && a2 >= a2k &&... a3 >= a3k的数从原来的集合中分开.ai表示pi的幂. 那么只有当这个数的素因子的最大幂都被询问过一次,这个数才能确定.因此答案是所有的不大于n的只有一个素因子的数. #include<bits/stdc++.h> using

hdoj 4828 卡特兰数取模

Grids Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 93    Accepted Submission(s): 25 Problem Description 度度熊近期非常喜欢玩游戏.这一天他在纸上画了一个2行N列的长方形格子. 他想把1到2N这些数依次放进去.可是为了使格子看起来优美,他想找到使每行每列都递增的方案.只是画了

HDU 5833 Zhu and 772002 (数论+高斯消元)

题目链接 题意:给定n个数,这n个数的素因子值不超过2000,从中取任意个数使其变成完全平方数,问有多少种取法. 题解:开始用素筛枚举写了半天TLE了,后来队友说高斯消元才想起来,果断用模板.赛后又得知这是个原题,真坑啊.把每个数进行素因子分解,素因子a的幂为奇数则视为1,偶数则视为0,转化为从n个数中取数异或和为0有多少种取法的问题. AC代码: #include <cstdio> #include <cstring> #include <cmath> #includ

bzoj 3309 反演

$n=p_1^{a_1}p_2^{a_2}…p_k^{a_k},p_i$为素数,定义$f(n)=max(a_1,a_2…,a_k)$. 给定a,b<=1e7求$\sum\limits_{i=1}^{a}\sum\limits_{j=1}^{b}f((i,j))$ 先简化. \begin{eqnarray*} \sum\limits_{i=1}^{a}\sum\limits_{j=1}^{b}f((i,j)) &=& \sum_{d=1}^{min(a,b)}\sum\limits_{

poj3358 Period of an Infimite Bimary Expansion

题目大意 链接 把分数转化为二进制小数,找出二进制小数的最小循环节长度以及开始位置. 思路 有理数n的第k位小数应为(n*2^k)mod\ 2 这里用分数p/q表示,则第 k 位小数位$(\frac{p}{q}*2^k)mod\ 2=(p*2^k)/q mod 2$,同时后k位小数为$(p*2^k )mod\ q$:若周期开始位置位x,长度为y,则$ (p*2^x\ mod\ q\equiv(p*2^{(x+y)} \ mod\ q$.y) 那么有 $q|p*2^x*(2^y-1)$ 由于p.q

【dfs/bfs+set+快速幂】swjtuOJ 2094

[dfs/bfs+set+快速幂]swjtuOJ 2094 [注:交大的看到这篇文章要学会自己写,不要为了比赛而比赛!~] 题目大意 问题一:主人公去度假,问经过a^b天后是星期几(简单题) 问题二:一个天平,n个重物,每个物体的重量wi已知,问能称出的所有重量有多少种? 问题二要注意到天平两侧都可以放重物,每一个重物的权值都可以赋值为w,0,-w,相当于三分,我们知道二分可以用二进制位运算进行枚举,例如:枚举所有子集 int j,k,top=0; int t = 1 << n; for(in