三十六、数学知识——组合数(递推法 + 预处理法 + 卢卡斯定理 + 分解质因数求解组合数 + 卡特兰数)

news2024/11/15 15:55:12

组合数算法主要内容

  • 一、基本思路
    • 1、组合数基本概念
    • 2、递推法——询问次数多 + a b 值较小 + 模处理(%mod)
    • 3、预处理阶乘方法——询问次数较多 + a b 值很大 + 模处理(%mod)
    • 4、卢卡斯定理——询问次数较少 + (a b 值很大) + mod模也很大
    • 5、分解质因数法(无模直接求解)——没有模运算 + 大数运算求解
    • 6、卡特兰数——多问题可转化为此问题 + 组合数求解
  • 二、Java、C语言模板实现
  • 三、例题题解

一、基本思路

1、组合数基本概念

  • 组合数:排列组合中的组合数,即给了a个人,从中选b个,问有多少种排列方方式: C b a C\begin{matrix} b \\ a \end{matrix} Cba
  • 公式如下:
    在这里插入图片描述

2、递推法——询问次数多 + a b 值较小 + 模处理(%mod)

  • 使用条件:
    • 1 - 10万组询问
    • 1 ≤ b ≤ a ≤ 2000
  • 公式如下:

在这里插入图片描述

  • 如何理解:
      1. 在进行选择的时候,包含需要的的一个(已选一个) C b − 1 a − 1 C\begin{matrix} b-1 \\ a-1 \end{matrix} Cb1a1
      1. 在进行选择的时候,不包含需要选的那个(1个未选) C b a − 1 C\begin{matrix} b \\ a-1\end{matrix} Cba1
    • 两种情况相加即为递推公式,即为所需内容。

3、预处理阶乘方法——询问次数较多 + a b 值很大 + 模处理(%mod)

  • 条件:
    • 1万次问询
    • 1 ≤ b ≤ a ≤ 10^5
  • 公式:

在这里插入图片描述

  • 分部求解:
    • a!阶乘求解 :

在这里插入图片描述

    • 1/((a-b)! * b!):
    • 已知:
      在这里插入图片描述
    • 求解:

*

    • 注意此处如果 mod 是质数则可以使用快速幂进行逆元求解,不是质数则需要使用扩展欧几里得算法进行逆元求解。
    • 组合求解:

*

  • 总结:

在这里插入图片描述

4、卢卡斯定理——询问次数较少 + (a b 值很大) + mod模也很大

  • 条件:
    • 20次询问;
    • 1 ≤ b ≤ a ≤ 10^18
    • 1 ≤ p ≤ 10^5
  • 定理:

*

  • 推导过程:(说实话没看懂,感觉可以直接背过模板进行计算)

在这里插入图片描述

5、分解质因数法(无模直接求解)——没有模运算 + 大数运算求解

  • 公式:
    在这里插入图片描述
  • 原理——分解质因数 + 大数运算求解

在这里插入图片描述

  • 步骤:

  • 当我们需要求出组合数的真实值,而非对某个数的余数时,分解质因数的方式比较好用:

    1. 筛法求出范围内的所有质数
    2. 通过 C(a, b) = a! / b! / (a - b)! 这个公式求出每个质因子的次数。 n! 中p的次数是 n / p + n / p^2 + n / p^3 + …
    3. 用高精度乘法将所有质因子相乘
  • 注意:说实话没怎么看懂,我还是背模板吧

6、卡特兰数——多问题可转化为此问题 + 组合数求解

  • 卡特兰数简介:
  • 卡特兰数是组合数学中一个常出现于各种计数问题中的数列。以中国蒙古族数学家明安图和比利时的数学家欧仁·查理·卡特兰的名字来命名,其前几项为(从第0项开始):1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …
    在这里插入图片描述
  • 卡特兰数结论:
    *
  • 卡特兰数推导(来自csdn作者:你好世界wxx):
    • 首先我们需要将上述问题转换成一个等价的问题:在一个二维平面内,从(0, 0)出发到达(n, n),每次可以向上或者向右走一格,0代表向右走一个,1代表向上走一格,则每条路径都会代表一个01序列,则满足任意前缀中0的个数不少于1个数序列对应的路径则右下侧,如下图:

在这里插入图片描述

    • 符合要求的路径必须严格在上图中红色线的下面(不可以碰到图中的红线,可以碰到绿线)。则我们考虑任意一条不合法路径,例如下图:

在这里插入图片描述
在这里插入图片描述

    • 补充:

在这里插入图片描述

  • 举例:
  • 给定 n 个 0和 n 个 1,它们将按照某种顺序排成长度为 2n 的序列,求它们能排列成的所有序列中,能够满足任意前缀序列中 0的个数都不少于 1 的个数的序列有多少个。输出的答案对 10^9+7取模。

在这里插入图片描述
在这里插入图片描述

  • 注意:
    • mod为质数进行逆元求解:快速幂
    • mod非质数求解逆元:扩展欧几里得算法

二、Java、C语言模板实现

  • 递推法:
// java 模板
static long[][] c = new long[N][N];
    
static void init(){         // 直接进行预处理,不用每次进行产生,就会减小时间复杂度
        
   for(int i = 0; i < N; i++){
       for(int j = 0; j <= i; j++){
           if(j == 0){
                c[i][j] = 1;
           }else{
                c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % Mod;    // c[i][j]实际上i是底数,j是选取的数,即 i = a, j = b;
           }
       }
    }
    
}
  • 预处理方法:
// java 模板
static int mod = (int)(1e9 + 7);
static long[] fact = new long[N];       // 使用 long 是为了防止爆 int
static long[] infact = new long[N];
    
static long qmi(long a, long k, long p){   // 快速幂求解逆元,其中k = mod - 2 使用费马定理求解逆元

   long res = 1; 
   while((k != 0)){
        if((k & 1) == 1){
            res = res * a % p;
        }
        k >>= 1;
        a = a * a % p;
  }     
  return res;
  
}
    
static void init(){    // 对fact[] infact[] 两个数组进行预处理,后面只需要简单计算即可以求出 
   fact[0] = 1;
   infact[0] = 1;
        
   for(int i = 1; i < N; i++){
       fact[i] = fact[i - 1] * i % mod;        // a! 阶乘求解
       infact[i] = infact[i - 1] * qmi(i, mod - 2, mod) % mod;   // 1/(b!) 阶乘倒数求解
   }
        
}

// 组合数求解
long result = (fact[a] * infact[b] % mod) * infact[a - b] % mod;
  • 卢卡斯定理:
// java 模板
static long p;
    
static long qmi(long a, long k){            // 快速幂求解
   long res = 1;
   while(k != 0){
     if((k & 1) == 1){
         res = res * a % p;
     }  
     k >>=1;
     a = a * a % p;
   }
   return res;
   
}
    
static long C(long a, long b){              
// 计算Cab,用的是预处理阶乘的方法————此处后面还会常用,一定要熟记,是进行Cab求解重要方法
   long res = 1;
   for(long i = 1,j = a; i <= b; i++,j--){
      res = res * j % p;
      res = res * qmi(i , p - 2)% p;      // qmi快速幂进行其中的逆元求解
   }
   return res;
}
    
static long lucas(long a, long b){      // 卢卡斯定理求解 Cab
  if(a < p && b < p){
     return C(a, b);                 // 不需要进行模处理,直接就可以计算
  }
  return C(a % p, b % p) * lucas(a/p, b/p) % p;       // 卢卡斯公式
}

  • 分解质因数法(无模直接求解):
// java 模板
static int[] sum = new int[N];
static int[] primes = new int[N];
static boolean[] st = new boolean[N];
static int cnt;

//线性筛筛质数
static void get_primes(int x){
  for(int i=2; i<=x; i++){
      if(!st[i]) primes[cnt++] = i;
      for(int j=0; primes[j]<=x/i; j++){
          st[primes[j]*i] = true;
          if(i%primes[j]==0) break;
      }
  }
}

//获得n!中某个质数的个数
static int get(int n, int p){
   int res = 0;
   while(n!=0){
      res+=n/p;
      n/=p;
   }
    return res;
}

// 主函数
get_primes(a);
for(int i=0; i<cnt; i++){
   int p = primes[i];
   sum[i] = get(a, p) - get(b, p) - get(a-b, p);   // 最终得到质数个数
}

BigInteger res = new BigInteger("1");       // 大数
for(int i=0; i < cnt; i++){                 // 质数个数
    int p = primes[i];
    for(int j=0; j<sum[i]; j++){
       res = res.multiply(new BigInteger(String.valueOf(p)));  // 阶乘求解
    }
}
        
  • 卡特兰数:
// Java模板
static long qmi(long a, long k){            // 快速幂求解质数逆元
  long res = 1;
  while(k != 0){
     if((k & 1) == 1){
        res = res * a % mod;
     }  
     k >>= 1;
     a = a * a % mod;
  }  
  return res;
  
}
    
static long C(long a, long b){              
// 此处求解 ab 范围不是很大的————组合数 % mod
// 假如ab范围更大的话,则需要使用卢卡斯定理
   long res = 1;
        
   for(long i = 1, j = a; i <= b;i++, j--){
      res = res * j % mod;
      res = res * qmi(i , mod - 2) % mod;
   }
   return res;
        
}

// 主函数
// !!!!!!可以用逆元来表示 (1/(n + 1)!)
long result = C(2 * n, n) * qmi(n + 1, mod - 2) % mod ;     // 此处用逆元来表示(1/(n + 1)!)
  • 扩展欧几里得算法:
import java.util.*;
public class Main{
    static int m = (int) 1e9 + 7;
    public static int exgcd(int a,int b,int[] x,int[] y){	// 扩展欧几里得算法
        if(b == 0){
            x[0] = 1; y[0] = 0;
            return a;
        }
        int d = exgcd(b,a % b,y,x);
        y[0] -= (a / b) * x[0] % m;
        return d;
    }
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        //卡特兰数公式;c[2n][n] - c[2n][n-1] = c[2n][n] / ( n + 1)
        int a = 2 * n;
        int b = n;
        int[] x = new int[1];
        int[] y = new int[1];
        long res = 1;
        for(int i = a ;i > a - b; i --) res = res * i % m;
        for(int i = 1 ; i <= n ; i ++ ){
            exgcd(i,m,x,y);
            res =( res * x[0] % m + m )% m;//同下
        }
        exgcd(n + 1, m,x,y);

        //这里是因为有可能x[0]是系数所以有可能是负数,所以模之后在加上一个m在模,就可以得到正
        res = (res * x[0]  % m + m) % m;
        System.out.println(res);
    }
}

  • C++模板
// C++ 模板,由yxc实现
1、递推法求组合数 —— 模板题 AcWing 885. 求组合数 I
// c[a][b] 表示从a个苹果中选b个的方案数
for (int i = 0; i < N; i ++ )
    for (int j = 0; j <= i; j ++ )
        if (!j) c[i][j] = 1;
        else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;


2、通过预处理逆元的方式求组合数 —— 模板题 AcWing 886. 求组合数 II
首先预处理出所有阶乘取模的余数fact[N],以及所有阶乘取模的逆元infact[N]
如果取模的数是质数,可以用费马小定理求逆元
int qmi(int a, int k, int p)    // 快速幂模板
{
    int res = 1;
    while (k)
    {
        if (k & 1) res = (LL)res * a % p;
        a = (LL)a * a % p;
        k >>= 1;
    }
    return res;
}

// 预处理阶乘的余数和阶乘逆元的余数
fact[0] = infact[0] = 1;
for (int i = 1; i < N; i ++ )
{
    fact[i] = (LL)fact[i - 1] * i % mod;
    infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
}

3、Lucas定理 —— 模板题 AcWing 887. 求组合数 III
若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;
}

4、分解质因数法求组合数 —— 模板题 AcWing 888. 求组合数 IV
当我们需要求出组合数的真实值,而非对某个数的余数时,分解质因数的方式比较好用:
    1. 筛法求出范围内的所有质数
    2. 通过 C(a, b) = a! / b! / (a - b)! 这个公式求出每个质因子的次数。 n! 中p的次数是 n / p + n / p^2 + n / p^3 + ...
    3. 用高精度乘法将所有质因子相乘

int primes[N], cnt;     // 存储所有质数
int sum[N];     // 存储每个质数的次数
bool st[N];     // 存储每个数是否已被筛掉


void get_primes(int n)      // 线性筛法求素数
{
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i]) primes[cnt ++ ] = i;
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}


int get(int n, int p)       // 求n!中的次数
{
    int res = 0;
    while (n)
    {
        res += n / p;
        n /= p;
    }
    return res;
}


vector<int> mul(vector<int> a, int b)       // 高精度乘低精度模板
{
    vector<int> c;
    int t = 0;
    for (int i = 0; i < a.size(); i ++ )
    {
        t += a[i] * b;
        c.push_back(t % 10);
        t /= 10;
    }

    while (t)
    {
        c.push_back(t % 10);
        t /= 10;
    }

    return c;
}

get_primes(a);  // 预处理范围内的所有质数

for (int i = 0; i < cnt; i ++ )     // 求每个质因数的次数
{
    int p = primes[i];
    sum[i] = get(a, p) - get(b, p) - get(a - b, p);
}

vector<int> res;
res.push_back(1);

for (int i = 0; i < cnt; i ++ )     // 用高精度乘法将所有质因子相乘
    for (int j = 0; j < sum[i]; j ++ )
        res = mul(res, primes[i]);

5、卡特兰数 —— 模板题 AcWing 889. 满足条件的01序列
给定n个0和n个1,它们按照某种顺序排成长度为2n的序列,满足任意前缀中0的个数都不少于1的个数的序列的数量为: Cat(n) = C(2n, n) / (n + 1)

三、例题题解

在这里插入图片描述

// java题解实现
// 递推法
import java.util.*;
import java.io.*;
public class Main{
    static int Mod = (int)(1e9 + 7);            // 此处的高次方值+7要用括号括起来
    static int N = 2010;
    static long[][] c = new long[N][N];
    
    static void init(){         // 直接进行预处理,不用每次进行产生,就会减小时间复杂度
        
        for(int i = 0; i < N; i++){
            for(int j = 0; j <= i; j++){
                if(j == 0){
                    c[i][j] = 1;
                }else{
                    c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % Mod;    // c[i][j]实际上i是底数,j是选取的数
                }
                
            }
        }
    }
    
    public static void main(String[] args) throws IOException {
        init();
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String str1 = in.readLine();
        int n = Integer.parseInt(str1);
        
        for(int i = 0; i < n; i++){
            String[] str2 = in.readLine().split(" ");
            int a = Integer.parseInt(str2[0]);
            int b = Integer.parseInt(str2[1]);
            System.out.println(c[a][b]);
        }
        
    }
}

在这里插入图片描述

// 预处理方法求解组合数
import java.util.*;
import java.io.*;

public class Main{
    static int N = 100010;          // 数据比较大使用此方法
    static int mod = (int)(1e9 + 7);
    static long[] fact = new long[N];       // 使用 long 是为了防止爆 int
    static long[] infact = new long[N];
    
    
    
    static long qmi(long a, long k, long p){        // 快速幂求解逆元,其中k = mod - 2 使用费马定理求解逆元
        long res = 1;
        
        while((k != 0)){
            if((k & 1) == 1){
                res = res * a % p;
            }
            k >>= 1;
            a = a * a % p;
        }
        
        return res;
        
    }
    
    static void init(){         // 对fact[] infact[] 两个数组进行预处理,后面只需要简单计算即可以求出 
        fact[0] = 1;
        infact[0] = 1;
        
        for(int i = 1; i < N; i++){
            fact[i] = fact[i - 1] * i % mod;        // a! 阶乘求解
            infact[i] = infact[i - 1] * qmi(i, mod - 2, mod) % mod; // 1/(b!)  阶乘倒数求解
        }
        
    }
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String str1 = in.readLine();
        
        int n = Integer.parseInt(str1);
        init();     // 预处理阶乘数组
        
        while(n-- != 0){
            String[] str2 = in.readLine().split(" ");
            int a = Integer.parseInt(str2[0]);
            int b = Integer.parseInt(str2[1]);
 
            System.out.println((fact[a] * infact[b] % mod) * infact[a - b] % mod);      
            // 组合数求解,组合数公式得来
        }
    }
}

在这里插入图片描述

// 卢卡斯定理需要解决的问题:
// 1、问询次数很小
// 2、组合数中的a,b,p范围很大
import java.util.*;
import java.io.*;

public class Main{
    static long p;
    
    static long qmi(long a, long k){            // 快速幂求解
        long res = 1;
        while(k != 0){
            if((k & 1) == 1){
                res = res * a % p;
            }
            
            k >>=1;
            a = a * a % p;
        }
        
        return res;
    }
    
    static long C(long a, long b){              // 计算Cab,用的是预处理阶乘的方法
        long res = 1;
        for(long i = 1,j = a; i <= b; i++,j--){
            res = res * j % p;
            res = res * qmi(i , p - 2)% p;      // qmi快速幂进行其中的逆元求解
        }
        return res;
    }
    
    static long lucas(long a, long b){      // 卢卡斯定理
        if(a < p && b < p){
            return C(a, b);                 // 不需要进行模处理,直接就可以计算
        }
        return C(a % p, b % p) * lucas(a/p, b/p) % p;       // 卢卡斯公式
    }
    
    
    
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String str1 = in.readLine();
        
        int n = Integer.parseInt(str1);
        
        while(n-- != 0){
            String[] str2 = in.readLine().split(" ");
            
            long a = Long.parseLong(str2[0]);   // 此处是将String转换成long类型
            long b = Long.parseLong(str2[1]);
            p = Long.parseLong(str2[2]);

            System.out.println(lucas(a, b));
        }
    }
}

在这里插入图片描述

// 分解质因数求解
import java.io.*;
import java.math.BigInteger;
import java.util.*;

class Main{
    static int N = 100010;
    static int[] sum = new int[N];
    static int[] primes = new int[N];
    static boolean[] st = new boolean[N];
    static int cnt;

    //线性筛筛质数
    static void get_primes(int x){
        for(int i=2; i<=x; i++){
            if(!st[i]) primes[cnt++] = i;
            for(int j=0; primes[j]<=x/i; j++){
                st[primes[j]*i] = true;
                if(i%primes[j]==0) break;
            }
        }
    }

    //获得n!中某个质数的个数
    static int get(int n, int p){
        int res = 0;
        while(n!=0){
            res+=n/p;
            n/=p;
        }
        return res;
    }

    public static void main(String[]args)throws IOException{
        BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
        String[]arr=in.readLine().split(" ");
        int a=Integer.parseInt(arr[0]);
        int b=Integer.parseInt(arr[1]);

        get_primes(a);

        for(int i=0; i<cnt; i++){
            int p = primes[i];
            sum[i] = get(a, p) - get(b, p) - get(a-b, p);   // 最终得到质数个数
        }

        BigInteger res = new BigInteger("1");       // 大数
        for(int i=0; i < cnt; i++){                 // 质数个数
            int p = primes[i];
            for(int j=0; j<sum[i]; j++){
                res = res.multiply(new BigInteger(String.valueOf(p)));  // 阶乘求解
            }
        }

        System.out.println(res);
    }
}

在这里插入图片描述

// 卡特兰数求解
import java.util.*;
import java.io.*;

public class Main{
    
    static int mod = (int)(1e9 + 7);
    
    static long qmi(long a, long k){            // 快速幂求解质数逆元
        long res = 1;
        while(k != 0){
            if((k & 1) == 1){
                res = res * a % mod;
            }
            
            k >>= 1;
            a = a * a % mod;
        }
        
        return res;
    }
    
    static long C(long a, long b){              
        // 此处求解 ab 范围不是很大的————组合数 % mod
        // 假如ab范围更大的话,则需要使用卢卡斯定理
        long res = 1;
        
        for(long i = 1, j = a; i <= b;i++, j--){
            res = res * j % mod;
            res = res * qmi(i , mod - 2) % mod;
        }
        
        return res;
        
    }
    
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        
        int n = Integer.parseInt(in.readLine());
        
        long result = C(2 * n, n) * qmi(n + 1, mod - 2) % mod ;     // 此处用逆元来表示(1/(n + 1))
        
        System.out.println(result);
        
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/623881.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

泰克AFG31051信号发生器产品参数

AFG31000系列任意波函数发生器 概述 验证连接 DUT 后输出波形 InstaView? 技术用在任意波函数发生器上可直接查看连接 DUT 后的实时波形&#xff0c;无需使用示波器或其他设备&#xff0c;节省测试时间并避免因阻抗不匹配导致的实验错误。 高保真度信号与高级模式 在连续模式…

软考高级架构师笔记-6计算机系统性能评价信息系统基础知识

目录 1. 前言 & 考情分析2. 系统配置与性能评价1. 性能指标2. 性能指标3. 阿姆达尔解决方案3.信息系统基础知识1.信息系统的分类2.信息系统的生命周期3.信息系统战略规划3.常见系统介绍1.客户关系管理CRM2.供应链管理SCM3.企业应用集成EAI4.结语1. 前言 & 考情分析 前…

VR全景创业是否真的赚钱?项目真的靠谱吗?

说到创业&#xff0c;也许你心里会觉得这类项目对于技术和资金等要求都是比较高的&#xff0c;先别急着反驳&#xff0c;这是大多数人的心理。我们选择某个创业项目时&#xff0c;都需要从创业成本和盈利利润来做预算&#xff0c;现在告诉你有一个VR全景创业项目&#xff0c;几…

爆火的AIGC到底是一片新蓝海,还是又一次的泡沫?

自ChatGPT发布以来&#xff0c;陷入了AIGC热&#xff0c;无论是大众的讨论、资本的流向还是大厂的加入&#xff0c;AIGC似乎都会是未来几年内最火的新蓝海。 不同于以往的“顶尖科技”泡沫&#xff0c;AIGC是真正可以应用到生活中的&#xff0c;这也是为何它会引发大量“失业论…

操作系统 复习--实训题

一. 简答题&#xff08;共8题&#xff0c;100分&#xff09; 1. (简答题) 编程使用fork()函数创建子进程&#xff0c;要求父进程中打印当前进程的 PID 和子进程的 PID&#xff0c;而在子进程中只打印当前进程的 PID。 参考代码&#xff1a; int main() { pid_t child_pid;c…

使用openlayers加载geoserver发布的arcgis瓦片

openlayers版本&#xff1a;6.5 geoserver版本&#xff1a;2.18.0 1. geoserver发布arcgis瓦片 首先去maven上面找最新的gwc-arcgiscache https://mvnrepository.com/artifact/org.geowebcache/gwc-arcgiscache/1.19.1 把这个jar包下载下来放到目录geoserver/WEB-INF/lib下面…

可扩展性与生态应用:Ardor公链AMA回顾

近日&#xff0c;Jelurida团队工程师Francisco Sarrias做客CryptoWallet.com&#xff0c;分享了一些有关Ardor的话题&#xff1a; Ardor是什么&#xff1f; Ardor是一个旨在提高区块链可扩展性的开源平台&#xff0c;这意味着该项目有助于使区块链网络运行更顺畅&#xff0c;用…

10分钟通过云服务器搭建自己的chatGPT镜像服务

通过云服务器搭建自己的chatGPT镜像服务 前提&#xff1a;需要有自己的API KEY 1 购买云服务器 本教程以阿里云的云服务器为例。 阿里云地址&#xff1a;https://www.aliyun.com/?spm5176.28008736.J_3207526240.1.769d3e4dTtNjuI 进入阿里云官网&#xff0c;选择云服务器ECS进…

精选博客系列|VMware如何实现多云基础设施

私有云&#xff0c;公有云&#xff0c;多云&#xff0c;边缘云… 如今&#xff0c;组织的团队、数据和工作负载分布在各种环境中。毫无疑问&#xff0c;这导致了技术上的复杂性增加、安全风险加剧、成本飙升和云战略不连贯的问题。 “39% 的高管难以在&#xff08;他们的&…

18.4:打印一个字符串的全部排列

打印一个字符串的全部排列 方法一&#xff1a;暴力方法。 //方法一&#xff1a;暴力方法。public static List<String> permutation1(String s) {//str是一个存储字符类型的有序表。ArrayList<Character> str new ArrayList<>();//将字符串中的类型存储在s…

Zookeeper概述

​ ZooKeeper概述 ZooKeeper是什么 zookeeper是一个为分布式应用程序提供的一个分布式开源协调服务框架。是Google的Chubby的一个开源实现&#xff0c;是Hadoop和Hbase的重要组件。主要用于解决分布式集群中应用系统的一致性问题。提供了基于类似Unix系统的目录节点树方式的数…

docker 安装 nsq

一. nsq介绍 nsq介绍 NSQ是一个基于Go语言&#xff0c;由bitly公司开源出来的一款简单易用的消息中间件。 官方和第三方开发了众多客户端功能库&#xff0c;如基于HTTP的nsqd、Go客户端go-nsq、Python客户端pynsq、基于Node.js的JavaScript客户端nsqjs、异步C客户端libnsq、J…

JavaSE-02【类型转换和运算符】

第一章&#xff1a;数据类型转换 Java程序中要求参与计算的数据&#xff0c;必须要保证数据类型的一致&#xff0c; 如果数据类型不一致则发生类型的转换1.1 自动转换 自动转换&#xff1a;将取值范围小的类型自动提升为取回范围大的类型 自动类型转换原理&#xff1a;一个i…

MySql锁知识记录积累(一)

1.关于脏读、幻读和不可重复读 脏读&#xff1a;一个事务A读取到了另一个事务B未提交的数据&#xff0c;叫做脏读 不可重复读&#xff1a;事务A被事务B干扰到了&#xff01;在事务A范围内&#xff0c;两个相同的查询&#xff0c;读取同一条记录&#xff0c;却反返回了不同的结…

运行一个新vue项目踩坑

npm install报错了&#xff0c;主要是因为node版本太高了。去node官网&#xff0c;下载低版本的msi后缀的文件&#xff0c;运行安装。在vs code里&#xff0c;npm下载依赖&#xff0c;并运行即可。 1. 无法cnpm cnpm : 无法加载文件 D:\Program Files\nodejs\node_global\cnpm.…

前端放大镜效果实现

放大镜效果实现 放大图片的需求&#xff0c;一般是在原有的渲染之上&#xff0c;额外添加一个放大框&#xff0c;当鼠标在原图上移动&#xff0c;放大框内就以当前的鼠标为中心&#xff0c;局部放大一定范围&#xff0c;在淘宝商城中是常有的实现。下面将用两种实现。 1、使用d…

是德 DSOX1202A示波器技术参数

KEYSIGHT是德科技 lnfiniiVision 1000 X 系列示波器是具有专业级功能的入门级示波器&#xff0c;配备的联网软件可提供远程控制和数据记录等功能。 它集 6 种仪器的功能于一身&#xff0c;属于是德科技智能测试台必备仪器之一。该系列包含 4 款独具特长的仪器&#xff0c;通过同…

5年功能测试要18K,一问三不知,还反过来怼我,真是醉了····

最近看了很多简历&#xff0c;很多候选人年限不小&#xff0c;但是做的都是一些非常传统的项目&#xff0c;想着也不能通过简历就直接否定一个人&#xff0c;何况现在大环境越来 越难&#xff0c;大家找工作也不容易&#xff0c;于是就打算见一见。 在沟通中发现&#xff0c;由…

坚持#第418天~久违了,二维码系统

公司有了一个新客户&#xff0c;这家客户的货物都是用铁架框装的&#xff0c;铁架框长得都一样&#xff0c;不好区分&#xff0c;只能看标签来识别&#xff0c;而且发货时需要一一核对发货单上的交货单号对应的货物&#xff0c;标签上的发货单号必须要一致才行&#xff0c;导致…

【干货】Kali Linux渗透基础知识大全,零基础入门必看!

最近好多朋友问我&#xff1a;不会编程&#xff0c;英语也不好&#xff0c;dos命令也记不住&#xff0c;能学习黑客技术么&#xff1f; 我可以明确告诉大家&#xff0c;可以的&#xff01; 相信每一个少年心中&#xff0c;曾经都有过一个黑客梦&#xff01; 有人觉得黑客霸气…