模板 - O(n)预处理,O(1)查询gcd

整理的算法模板合集: ACM模板


基于值域预处理的快速 GCD算法

给定 n n n 个正整数 a 1 , a 2 , … , a n a_1,a_2,\dots,a_n a1,a2,,an ,再给定 n n n 个正整数 b 1 , b 2 , … , b n b_1,b_2,\dots,b_n b1,b2,,bn ,你需要对每对 ( i , j ) (i,j) (i,j)求出 a i a_i ai b j b_j bj 的最大公因数。

不难发现你的输出应有 n 2 n^2 n2 个正整数。为了减少输出对程序的运行效率的影响,你只需要输出 nn 行,每行一个整数 A i A_i Ai

其中对于 i ∈ [ 1 , n ] i ∈ [ 1 , n ] , A i = ∑ j = 1 n i j gcd ⁡ ( a i , b j ) A i\in[1,n]i∈[1,n],A_i=\sum_{j=1}^{n}i^j\gcd(a_i,b_j)A i[1,n]i[1,n]Ai=j=1nijgcd(ai,bj)A。由于答案可能过大,你只需要输出模 998 , 244 , 353 998,244,353 998,244,353 后的结果即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>

using namespace std;
typedef long long ll;

const int N = 5000, M = 1000000, T = 1000, Mod = 998244353;

int pre[T + 2][T + 2];
int a[N + 2], b[N + 2];
int fac[M + 2][3];
bool isp[M + 2];
int pri[M / 10], tot;
int n;

inline int read()
{
	int re=0,k=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')k=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){re=re*10+ch-48;ch=getchar();}
	return re*k;
}


inline void write(int x)
{
	if(x<10)
	{
		putchar(x+48);
		return;
	}
	write(x/10),write(x%10);
}

void work() {
    fac[1][0] = fac[1][1] = fac[1][2] = 1;

    for (int i = 2; i <= M; ++i) {
        if (!isp[i]) {
            fac[i][0] = fac[i][1] = 1;
            fac[i][2] = i;
            pri[++tot] = i;
        }

        for (int j = 1; pri[j] * i <= M; ++j) {
            int tmp = pri[j] * i;
            isp[tmp] = true;
            fac[tmp][0] = fac[i][0] * pri[j];
            fac[tmp][1] = fac[i][1];
            fac[tmp][2] = fac[i][2];

            if (fac[tmp][0] > fac[tmp][1]) {
                fac[tmp][0] ^= fac[tmp][1] ^= fac[tmp][0] ^= fac[tmp][1];
            }

            if (fac[tmp][1] > fac[tmp][2]) {
                fac[tmp][1] ^= fac[tmp][2] ^= fac[tmp][1] ^= fac[tmp][2];
            }

            if (i % pri[j] == 0) {
                break;
            }
        }
    }

    for (int i = 0; i <= T; ++i) {
        pre[0][i] = pre[i][0] = i;
    }

    for (int i = 1; i <= T; ++i) {
        for (int j = 1; j <= i; ++j) {
            pre[i][j] = pre[j][i] = pre[j][i % j];
        }
    }
}

int gcd(int a, int b) {
    int ans = 1;
    for (int i = 0; i < 3; ++i) {
        int tmp = (fac[a][i] > T) ?
                  (b % fac[a][i] ?
                   1
                   : fac[a][i]
                  )
                  : pre[fac[a][i]][b % fac[a][i]];
        b /= tmp;
        ans *= tmp;
    }

    return ans;
}

int main()
{
    work();
    n = read();

    for (int i = 1; i <= n; ++i)
        a[i] = read();
    for (int i = 1; i <= n; ++i)
        b[i] = read();
    for (int i = 1; i <= n; ++i) {
        int ans = 0;
        for (int j = 1, now = i; j <= n; ++j, now = now * 1ll * i % Mod) {
            ans = (ans + int(now * 1ll * gcd(a[i], b[j]) % Mod)) % Mod;
        }
        write(ans);
        puts("");
    }
    return 0;
}
已标记关键词 清除标记
课程简介: 历经半个多月的时间,Debug亲自撸的 &ldquo;企业员工角色权限管理平台&rdquo; 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的&ldquo;项目实战&rdquo;课程,即&ldquo;企业应用员工角色权限管理平台&rdquo;,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:设计师小姐姐 返回首页