math

求100!的约数个数和约数之和

package lanqiao;
import java.util.*;
public class math0 {
    static List<Integer>primes=new LinkedList<Integer>();
    static void sPrime(int n) {
        boolean[]st=new boolean[n+1];
        for(int i=2;i<=n;i++) {
            if(!st[i])primes.add(i);
            for(int j=0;primes.get(j)*i<=n;j++) {
                st[primes.get(j)*i]=true;
                if(i%primes.get(j)==0)break;
            }
        }
    }
    static int minc(int n,int p) {
        int rxp=0;
        while(n>0) {
            n/=p;
            rxp+=n;
        }
        return rxp;
    }
    static long qui(long a,long b) {
        long res=1;
        while(b>0) {
            if((b&1)==1) {
                res*=a;
            }
            a=a*a;
            b/=2;
        }
        return res;
    }
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int n=100;
        sPrime(n);
        int []exp=new int[primes.size()];
        for(int i=0;i<primes.size();i++) {
            int p=primes.get(i);
            exp[i]=minc(n,p);
        }
        int numy=1;
        for(int e:exp) {
            numy*=(e+1);
        }
        long sumy=1L;
        for(int i=0;i<primes.size();i++) {
            int p=primes.get(i);
            int e=exp[i];
            sumy*=(qui(p,e+1)-1)/(p-1);
        }
        System.out.println(numy+"  "+sumy);
        scan.close();
    }
}

质因数分解

import java.util.HashMap;
import java.util.Map;

public class PrimeFactorization {
    public static void main(String[] args) {
        int x = 100; // 待分解的数
        Map<Integer, Integer> primeFactors = divide(x);

        // 输出质因数及其次数
        for (Map.Entry<Integer, Integer> entry : primeFactors.entrySet()) {
            System.out.println(entry.getKey() + " " + entry.getValue());
        }
    }

    public static Map<Integer, Integer> divide(int x) {
        Map<Integer, Integer> primeFactors = new HashMap<>();

        for (int i = 2; i <= x / i; i++) {
            if (x % i == 0) {
                int count = 0;
                while (x % i == 0) {
                    x /= i;
                    count++;
                }
                primeFactors.put(i, count);
            }
        }

        // 如果最后剩下的x > 1,说明它本身是质数
        if (x > 1) {
            primeFactors.put(x, 1);
        }

        return primeFactors;
    }
}

欧拉函数(Euler’s Totient Function)

欧拉函数 ϕ(n)ϕ(n) 表示小于或等于 nn 的正整数中与 nn 互质的数的个数。
性质

  • n是质数,ϕ(n)=n−1ϕ(n)=n−1。
  • 若 n=pkn=*pk,ϕ(n)=pk−pk−1ϕ(n)=pkp*k−1。
  • 若 n=a×bn=a×b 且 aa 和 bb 互质,ϕ(n)=ϕ(a)×ϕ(b)ϕ(n)=ϕ(aϕ(b)。
public class EulerTotient {
    public static int eulerTotient(int n) {
        int result = n;
        for (int p = 2; p * p <= n; p++) {
            if (n % p == 0) {
                while (n % p == 0) {
                    n /= p;
                }
                result -= result / p;
            }
        }
        if (n > 1) {
            result -= result / n;
        }
        return result;
    }

    public static void main(String[] args) {
        int n = 10;
        System.out.println("欧拉函数φ(" + n + ") = " + eulerTotient(n));
    }
}

别考,求!

卢卡斯定理(Lucas Theorem)及其适用性

卢卡斯定理的表述

若 pp 是质数,则对于任意整数 1≤m≤n1≤mn,组合数 C(n,m)C(n,m) 满足:

C(n,m)≡C(n mod p,m mod p)×C(⌊np⌋,⌊mp⌋)(modp)C(n,m)≡C(nmodp,mmodpC(⌊*pn⌋,⌊pm⌋)(modp*)

其中:

  • C(n mod p,m mod p)C(nmodp,mmodp) 是 小规模组合数(直接用公式计算)。
  • C(⌊np⌋,⌊mp⌋)C(⌊*pn⌋,⌊pm*⌋) 是 递归计算的组合数

适用条件

  1. p*p* 必须是质数,否则卢卡斯定理不成立。
  2. 适用于 n*n* 和 m*m* 较大的情况(如 n,m≤1018n,m≤1018,但 pp 较小)。
  3. 不适用于非质数模数(如 p=4p=4 或 p=109+7p=109+7 但非质数)。
若p是质数,则对于任意整数 1 <= m <= n,有:
    C(n, m) = C(n % p, m % p) * C(n / p, m / p) (mod p)

int qmi(int a, int k, int p)  // 快速幂模板
{
    int res = 1 % p;
    while (k)
    {
        if (k & 1) res = (LL)res * a % p;
        a = (LL)a * a % p;
        k >>= 1;
    }
    return res;
}

int C(int a, int b, int p)  // 通过定理求组合数C(a, b)
{
    if (a < b) return 0;

    LL x = 1, y = 1;  // x是分子,y是分母
    for (int i = a, j = 1; j <= b; i --, j ++ )
    {
        x = (LL)x * i % p;
        y = (LL) y * j % p;
    }

    return x * (LL)qmi(y, p - 2, p) % p;
}

int lucas(LL a, LL b, int p)
{
    if (a < p && b < p) return C(a, b, p);
    return (LL)C(a % p, b % p, p) * lucas(a / p, b / p, p) % p;
}

扩展卢卡斯定理(Lucas Theorem)

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExLucas {

    // 质因数分解 p = p1^k1 * p2^k2 * ... * pm^km
    public static Map<Integer, Integer> factorize(int p) {
        Map<Integer, Integer> factors = new HashMap<>();
        for (int i = 2; i * i <= p; i++) {
            while (p % i == 0) {
                factors.put(i, factors.getOrDefault(i, 0) + 1);
                p /= i;
            }
        }
        if (p > 1) factors.put(p, 1);
        return factors;
    }

    // 计算 n! 中去除 p 的因子后的值 mod p^k
    public static int factorialMod(int n, int p, int pk) {
        if (n == 0) return 1;
        int res = 1;
        for (int i = 1; i <= pk; i++) {
            if (i % p == 0) continue; // 跳过 p 的倍数
            res = (res * i) % pk;
        }
        res = powMod(res, n / pk, pk);
        for (int i = 1; i <= n % pk; i++) {
            if (i % p == 0) continue;
            res = (res * i) % pk;
        }
        return (res * factorialMod(n / p, p, pk)) % pk;
    }

    // 快速幂算法
    public static int powMod(int base, int exp, int mod) {
        int result = 1;
        base = base % mod;
        while (exp > 0) {
            if (exp % 2 == 1) {
                result = (result * base) % mod;
            }
            exp = exp >> 1;
            base = (base * base) % mod;
        }
        return result;
    }

    // 计算 n! 中 p 的幂次
    public static int countP(int n, int p) {
        int count = 0;
        while (n > 0) {
            n /= p;
            count += n;
        }
        return count;
    }

    // 计算 C(n, m) mod p^k
    public static int combModPk(int n, int m, int p, int pk) {
        if (m > n) return 0;
        int num = factorialMod(n, p, pk);
        int den1 = factorialMod(m, p, pk);
        int den2 = factorialMod(n - m, p, pk);
        int den = (den1 * den2) % pk;
        int invDen = modInverse(den, pk); // 逆元
        int powP = countP(n, p) - countP(m, p) - countP(n - m, p);
        return (num * invDen % pk * powMod(p, powP, pk)) % pk;
    }

    // 计算模逆元
    public static int modInverse(int a, int m) {
        return powMod(a, m - 2, m);
    }

    // 中国剩余定理(CRT)合并同余方程
    public static int crt(List<Integer> remainders, List<Integer> mods) {
        int M = 1;
        for (int mod : mods) {
            M *= mod;
        }
        int res = 0;
        for (int i = 0; i < remainders.size(); i++) {
            int mi = mods.get(i);
            int Mi = M / mi;
            int invMi = modInverse(Mi, mi);
            res = (res + remainders.get(i) * Mi % M * invMi % M) % M;
        }
        return res;
    }

    // 扩展卢卡斯定理:计算 C(n, m) mod p(p 非质数)
    public static int exLucas(int n, int m, int p) {
        Map<Integer, Integer> factors = factorize(p);
        List<Integer> remainders = new ArrayList<>();
        List<Integer> mods = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : factors.entrySet()) {
            int prime = entry.getKey();
            int exp = entry.getValue();
            int pk = (int) Math.pow(prime, exp);
            int rem = combModPk(n, m, prime, pk);
            remainders.add(rem);
            mods.add(pk);
        }
        return crt(remainders, mods);
    }

    public static void main(String[] args) {
        int n = 100;
        int m = 50;
        int p = 12; // 非质数模数
        int result = exLucas(n, m, p);
        System.out.println("C(" + n + ", " + m + ") mod " + p + " = " + result);
    }
}

并查集

import java.util.*;
public class Main{
  static int[]father;
  static long[]value;
  public static void main(String[] args){
    Scanner scan=new Scanner(System.in);
    int N=scan.nextInt();
    int M=scan.nextInt();
    int Q=scan.nextInt();
    father=new int[N+1];
    value=new long[N+1];
    init(N);
    for(int i=0;i<M;i++){
      int left=scan.nextInt();
      int right=scan.nextInt();
      long s=scan.nextLong();
      left--;
      union(left,right,s);
    }
    for(int i=0;i<Q;i++){
      int l=scan.nextInt();
      int r=scan.nextInt();
      l--;
      int lFa=find(l);
      int rFa=find(r);
      if(lFa==rFa){
        System.out.println(value[l]-value[r]);
      }else{
        System.out.println("UNKNOWN");
      }
    }
    scan.close();
  }
  static void init(int N){
    for(int i=0;i<=N;i++){
      father[i]=i;
    }
  }
  static int find(int x){
    if(x!=father[x]){
      int tmp=father[x];
      father[x]=find(father[x]);
      value[x]+=value[tmp];
    }
    return father[x];
  }
  static void union(int left,int right,long s){
    int lF=find(left);
    int rF=find(right);
    if(lF!=rF){
      int min=Math.min(lF,rF);
      int max=Math.max(lF,rF);
      father[min]=max;
      value[min]=Math.abs(value[right]-value[left]+s);
    }
  }
}
import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
  static int N=110;
  static int n,Q;
  static long[][]cnt;
  static long[][]ans;
  static long[][]lns;
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n=scan.nextInt();
        Q=scan.nextInt();
        cnt=new long[N][N];
        ans=new long[N][N];
        lns=new long[N][N];
        for(int i=1;i<=n;i++){
          for(int j=1;j<=n;j++){
            ans[i][j]=scan.nextLong();
          }
        }
        for(int i=1;i<=n;i++){
          for(int j=1;j<=n;j++){
            lns[i][j]=scan.nextInt();
            cnt[i][j]=lns[i][j];
          }
        }
        if(floyd()>Q){
          System.out.println(-1);
          return;
        }
        long l=0,r=10000010;
        while(l<r){
          long mid=l+r>>1;
          if(check(mid))r=mid;//minhua
          else l=mid+1;
        }
        System.out.println(r);
        scan.close();
    }
    static long floyd(){
      //最短路下线
      long a=0;
      for(int k=1;k<=n;k++){
          for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
              cnt[i][j]=Math.min(cnt[i][j],cnt[i][k]+cnt[k][j]);
            }
          }
        }
        for(int i=1;i<=n;i++){
          for(int j=1;j<=n;j++){
            a+=cnt[i][j];
          }
        }
        return a;
    }
    static boolean check(long x){
      for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
          cnt[i][j]=ans[i][j];
        }
      }
      long h=x/n;
      long s=x%n;
      for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
          if(i==j)continue;
          if(i<=s)cnt[i][j]=Math.max(lns[i][j],cnt[i][j]-1-h);
          else cnt[i][j]=Math.max(lns[i][j],cnt[i][j]-h);
          cnt[j][i]=cnt[i][j];
        }
      }
      return floyd()<=Q;
    }
}

dij

package lanqiao;
import java.util.*;
public class dj {
    static int m,n;
    static long[][]dis;
    static boolean[][]st;
    static ArrayList<long[]>[][]list;
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        n=scan.nextInt();
        m=scan.nextInt();
        dis=new long[n+1][m+1];
        st=new boolean[n+1][m+1];
        int[][]a=new int[n+1][m+1];
        list=new ArrayList[n+1][m+1];
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                list[i][j]=new ArrayList<long[]>();
                a[i][j]=scan.nextInt();
            }
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
            if(i>1)list[i][j].add(new long[] {i-1,j,a[i-1][j]});
            if(j>1)list[i][j].add(new long[] {i,j-1,a[i][j-1]});
            if(i<n)list[i][j].add(new long[] {i+1,j,a[i+1][j]});
            if(j<m)list[i][j].add(new long[] {i,j+1,a[i][j+1]});
            }
        }
        dij(a[1][1]);
        long max=0;
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=m;j++) {
                max=Math.max(dis[i][j],max);
            }
        }
        System.out.println(max);
        scan.close();
    }
    static void dij(int start) {
        for(int i=1;i<=n;i++) {
            Arrays.fill(dis[i],Long.MAX_VALUE);
        }

        PriorityQueue<long[]>p=new PriorityQueue<long[]>(Comparator.comparing(k->k[2]));
        dis[1][1]=start;
        p.add(new long[]{1,1,start});
        while(!p.isEmpty()) {
            long[]t=p.poll();
            int x=(int)t[0];
            int y=(int)t[1];
            if(st[x][y])continue;
            st[x][y]=true;
            for(long[]a:list[x][y]) {
                int x1=(int)a[0];
                int y1=(int)a[1];
                long w=a[2];
                if(dis[x1][y1]>dis[x][y]+w) {
                    dis[x1][y1]=dis[x][y]+w;
                    p.add(new long[] {x1,y1,dis[x1][y1]});
                }
            }
        }

    }

}

dfs

import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
  static int N=110;
  static int n,Q;
  static long[][]cnt;
  static long[][]ans;
  static long[][]lns;
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        n=scan.nextInt();
        Q=scan.nextInt();
        cnt=new long[N][N];
        ans=new long[N][N];
        lns=new long[N][N];
        for(int i=1;i<=n;i++){
          for(int j=1;j<=n;j++){
            ans[i][j]=scan.nextLong();
          }
        }
        for(int i=1;i<=n;i++){
          for(int j=1;j<=n;j++){
            lns[i][j]=scan.nextInt();
            cnt[i][j]=lns[i][j];
          }
        }
        if(floyd()>Q){
          System.out.println(-1);
          return;
        }
        long l=0,r=10000010;
        while(l<r){
          long mid=l+r>>1;
          if(check(mid))r=mid;//minhua
          else l=mid+1;
        }
        System.out.println(r);
        scan.close();
    }
    static long floyd(){
      //最短路下线
      long a=0;
      for(int k=1;k<=n;k++){
          for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
              cnt[i][j]=Math.min(cnt[i][j],cnt[i][k]+cnt[k][j]);
            }
          }
        }
        for(int i=1;i<=n;i++){
          for(int j=1;j<=n;j++){
            a+=cnt[i][j];
          }
        }
        return a;
    }
    static boolean check(long x){
      for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
          cnt[i][j]=ans[i][j];
        }
      }
      long h=x/n;
      long s=x%n;
      for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
          if(i==j)continue;
          if(i<=s)cnt[i][j]=Math.max(lns[i][j],cnt[i][j]-1-h);
          else cnt[i][j]=Math.max(lns[i][j],cnt[i][j]-h);
          cnt[j][i]=cnt[i][j];
        }
      }
      return floyd()<=Q;
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇