约数个数

sloj #P4001. 约数个数

题目描述

给出整数x,求它的约数个数

为了加大难度,有m次询问,将每次询问的答案求和然后mod109+7

输入格式

第一行是一个整数m

第二行是整数q1,a,b,c

q1表示第一次询问的数字

第i次询问qi=(qi1a+b)%c

输出格式

所有询问的答案之和mod109+7

样例

输入数据 1

2 
2 2 1 9

输出数据 1

4

数据规模与约定

100%的数据保证 A,B,C<=107,1<=Q1<=C。

 要做这道题,首先你得知道:n = p1c1*p2c2*p3c3*……*pici这些应该都知道吧,就是质(只)因式分解我是小黑子不知道的可以出门左转了

还要知道:d(因数个数) = (c1+1)*(c2+1)*(c3+1)*……*(ci+1)

上面那俩都是小学奥数吧,不会的可以让你妈再生一个了,这号基本练废了

证明我就不在这里放出了,这很显然嘛

设e[i]表示最小质(只)因子出现次数,g[i]为约数个数,因为线性筛只用得到最小质(只)因子,对于素数,明显有g[i] = 2,e[i] = 1

如果是合数,那么就有e[k] = e[i]+1; g[k] = (g[i]/(e[i]+1)*(e[k]+1));

e[k]为当前最小质因子出现次数

g[i]需要先除一个e[i]+1则是因为变更这个最小质因子时要把原来算的先给除去才能得到正确答案

不然就是会变为个d = (c1+1)*(c2+1)*(c3+1)*……(ci+1)*((ci+1)+1)

如果还没看懂那就直接抄代码去吧,绝对不是我讲不清楚了

注意:如果这个质因子第一次出现则是个g[k] = g[i]*2

分析完毕,上代码

复制代码
#include<bits/stdc++.h>
#define ll long long
#define mod 1000000007
using namespace std;
int q,a,b,c,m,g[10000010],e[10000010],vis[10000010],prime[10000010],cnt;
ll ans = 0;
void pre(){
    g[1] = 1;
    for(int i = 2;i<=c;i++){
        if(!vis[i]){
            prime[++cnt] = i;
            e[i] = 1;
            g[i] = 2;
        }
        for(int j = 1;j<=cnt&&i*prime[j]<=c;j++){
            int k = i*prime[j];
            vis[k] = 1;
            if(i%prime[j]==0){
                e[k] = e[i]+1;
                g[k] = (g[i]/(e[i]+1)*(e[k]+1));
                break;
            }
            e[k] = 1;
            g[k] = g[i]*2;
        }
    }
}
int main(){
    scanf("%d%d%d%d%d",&m,&q,&a,&b,&c);
    pre();
    ans = g[q]%mod;
    for(int i = 2;i<=m;i++){
        q = ((long long)q*a+b)%c;
        ans+=g[q]%mod;
    }
    printf("%lld",ans);
    return 0;
}
复制代码

 

posted @   cztq  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示