阶乘的约数和、斐波那契数列、数列区间最大值(ST表)

阶乘的约数和

问题描述

给定你一个正整数 nn,你需要求出 n!n! 的约数之和,结果对 998244353998244353 取模。

n!n!:nn 的阶乘,含义为 1×2×3×...×n1×2×3×...×n。

输入格式

输入包含一个正整数 nn。

输出格式

输出 n!n! 的约数之和,对 998244353998244353 取模。

样例输入

复制代码
20

样例输出

复制代码
843703748

评测数据规模

1≤n≤2×1051≤n≤2×105。

复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;




public class Main {

    static int N = 2*100010,mod=998244353,ind;
    static int prime[]=new int[N];
    static int a[]=new int[N];
    static boolean f[]=new boolean[N];
   
    public static void main(String[] args) throws IOException {
    	
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n=Integer.parseInt(br.readLine());
//        String g[] = br.readLine().split(" ");
//        int n=Integer.parseInt(g[0]);
        get_Prime(n);//n的阶乘只能分解出n以内的质数
        int nn=n;
        for (int i = 0; i < ind; i++) {
			while(n/prime[i]>0){
				n=n/prime[i];
				a[i]+=n;
				
			}
			n=nn;
		}
        long  res=1;
//每个p的多项式可以用等比数列的和求出,这里有除法取模 所以必须用逆元
        for (int i = 0; i < ind; i++) {
			res=(res*(reverseInfo(prime[i], a[i]+1)-1)%mod*reverseInfo(prime[i]-1,mod-2)%mod);
		}
       System.out.println(res);
    }
    
    static long reverseInfo(long a,int p){
    	long res=1;
    	
    	while(p>0){
    		if((p&1)==1){
    			res=res*a%mod;
    		}
    		a=a*a%mod;
    		p=p>>1;
    	}
    	return res%mod;
    }
    static void get_Prime(int n){
    	for (int i = 2; i <= n; i++) {
			if(!f[i])prime[ind++]=i;
			for (int j = 0; j < ind && i*prime[j]<=n; j++) {
			  	f[i*prime[j]]=true;
			  	if(i%prime[j]==0)break;
			}
		}
    }
}

斐波那契数列

斐波那契数列

题目描述

斐波那契数列:{F(1)=F(2)=1F(n)=F(n−1)+F(n−2)n>2,n∈N∗{F(1)=F(2)=1F(n)=F(n−1)+F(n−2)​​n>2,n∈N∗​

给定一个正整数 NN,求F(N)F(N)在模 109+7109+7 下的值。

输入描述

第 11 行为一个整数 TT,表示测试数据数量。

接下来的 TT 行每行包含一个正整数 NN。

1≤T≤1041≤T≤104,1≤N≤10181≤N≤1018。

输出描述

输出共 TT 行,每行包含一个整数,表示答案。

输入输出样例

示例 1

输入

复制代码
6
1
2
3
4
5
1000000000

输出1 1 2 3 5 21

复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;






public class Main {

    static int N = 2*100010,mod=(int)1e9+7,ind;
//    static int prime[]=new int[N];
//    static int a[]=new int[N];
//    static boolean f[]=new boolean[N];
    static long right[][]=new long[1][2];
    static long left[][]={{1,1}};
    static long a[][]={{1,1},{1,0}};
    public static void main(String[] args) throws IOException {
    
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t=Integer.parseInt(br.readLine());
//        String g[] = br.readLine().split(" ");
//        int n=Integer.parseInt(g[0]);
       for (int i = 0; i < t; i++) {
		long n=Long.parseLong(br.readLine());
		 long aa[][] = matrixQuickMi(a,n-2);
		 System.out.println((aa[0][0]+aa[1][0])%mod);
	   }
    }
    static long[][] matrixQuickMi(long a[][],long p){
    	long res[][]={{1,0},{0,1}};
    	while(p>0){
    		if((p&1)==1){
    			res=multiple(res,a);
    		}
    		p=p>>1;
    		a=multiple(a,a);
    	}
    	return res;
    }
   static long[][] multiple(long a[][],long b[][]){
	   long res[][]=new long[2][2];
	   for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			for (int j2 = 0; j2 < 2; j2++) {
				res[i][j]=(long)(res[i][j]+a[i][j2]*b[j2][j])%mod;
			}
		}
	   }
	   return res;
   }
}

数列区间最大值

输入一串数字,给你 M 个询问,每次询问就给你两个数字 X,Y,要求你说出 X 到 Y 这段区间内的最大数。

输入格式

第一行两个整数 N,M 表示数字的个数和要询问的次数;

接下来一行为 N 个数;

接下来 M 行,每行都有两个整数 X,Y。

输出格式

输出共 M 行,每行输出一个数。

数据范围

1≤N≤105,

1≤M≤106,

1≤X≤Y≤N,

数列中的数字均不超过231−1

输入样例:
复制代码
10 2
3 2 4 5 6 8 1 2 9 7
1 4
3 8
输出样例:
复制代码
5
8
复制代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;


public class Main {

    static int N = 100010,M=(int)(Math.log(N)/Math.log(2)+1);
    
    static int lg2[]=new int[N];
    static int a[]=new int[N];
    static int f[][]=new int[N][M];//表示以i为起点 长度为2^j的区间内的最大值
    static BufferedWriter bw =new BufferedWriter(new OutputStreamWriter(System.out));
    public static void main(String[] args) throws IOException {
    	
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        //int t=Integer.parseInt(br.readLine());
        String g[] = br.readLine().split(" ");
        int n=Integer.parseInt(g[0]),m=Integer.parseInt(g[1]);
        g = br.readLine().split(" ");
        for (int i = 1; i <= n; i++) {
			a[i]=Integer.parseInt(g[i-1]);
		}
        lg2[1]=0;
        for (int i = 2; i <= n; i++) {
			lg2[i]=lg2[i/2]+1;
		}
        //f[i][j]=max(f[i][j-1],f[i+2^(j-1)][j-1]
        //f[i][j]=ai
      
       for (int j = 0; j <= lg2[n]; j++) {
		  for (int i = 1;i + (1<<j) - 1<= n; i++) {
			//区间为[i,i+2^(j-1)-1]
			 if(j==0)f[i][0]=a[i];
			 else f[i][j]=Math.max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
		  }
	   }
        
        for (int i = 1; i <= m; i++) {
        	 g = br.readLine().split(" ");
        	 int l=Integer.parseInt(g[0]),r=Integer.parseInt(g[1]);
        	 query(l,r);
		}
      
    }
    static void query(int l,int r) throws IOException{
    	int len=r-l+1;
    	int k=lg2[len];
    	//第一个区间[l,l+(1<<k)-1]  第二个个区间[r-(1<<k)+1,r] 
    	//两个区间有重叠 也可以
    	 int res=Math.max(f[l][k], f[r-(1<<k)+1][k]);
       bw.write(res+"\n");
    	bw.flush();
    }
}
相关推荐
智者知已应修善业1 小时前
【51单片机象棋快棋赛 电子裁判器】2023-12-27
c++·经验分享·笔记·算法·51单片机
晚风予卿云月1 小时前
二分算法练习
数据结构·c++·算法·竞赛·算法随笔
菜菜的顾清寒1 小时前
力扣HOT100(47) 二叉树的层序遍历
算法·leetcode·深度优先
周末也要写八哥1 小时前
牛顿迭代Python代码实现
算法
KaMeidebaby2 小时前
卡梅德生物技术快报|基因测序技术在 46,XY 性发育障碍变异筛查中的流程与数据分析
服务器·前端·数据库·人工智能·算法·数据挖掘·数据分析
ZengLiangYi2 小时前
SourceAdapter 插件架构详解
javascript·算法·架构
妄想出头的工业炼药师2 小时前
特征检测和特征筛选
算法·开源
cxr8282 小时前
高分子复合材料 AI 逆向设计合——学证明、算法实现、验证数据与学术资源全集
人工智能·线性代数·算法
ZengLiangYi2 小时前
如何解析 5 种完全不同格式的 AI 对话
javascript·人工智能·算法