2721: [Violet 5]樱花|约数个数

先跪一发题目背景QAQ

显然x,y>n!,然后可以设y=n!+d

原式子可以化简成

x=n!2d+n!

那么解的个数也就是n!的因子个数,然后线性筛随便搞一搞

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define N 1000008
#define mod  1000000007
using namespace std;
int sc()
{
    int i=0,f=1; char c=getchar();
    while(c>‘9‘||c<‘0‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘)i=i*10+c-‘0‘,c=getchar();
    return i*f;
}
long long ans=1;
int lo[N],low[N],a[N],prime[N],s[N],top;
int sum[N],n;
void pre(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!a[i])
            s[prime[++top]=low[i]=lo[i]=i]=1;
        for(int j=1;prime[j]*i<=n;j++)
        {
            a[i*prime[j]]=1;
            lo[i*prime[j]]=prime[j];
            if(i%prime[j]==0)
            {
                low[i*prime[j]]=low[i]*prime[j];
                s[i*prime[j]]=s[i]+1;
                break;
            }
            low[i*prime[j]]=prime[j];
            s[i*prime[j]]=1;
        }
    }
}
int main()
{
    pre(n=sc());
    for(int i=2;i<=n;i++)
    {
        int now=i;
        while(now!=1)
            sum[lo[now]]+=2*s[now],now/=low[now];
    }
    for(int i=1;i<=n;i++)
        ans=ans*(sum[i]+1)%mod;
    cout<<ans;
    return 0;
}
时间: 2024-12-29 10:35:09

2721: [Violet 5]樱花|约数个数的相关文章

BZOJ 2721 Violet 5 樱花 数论

题目大意:给定n,求有多少正整数数对(x,y)满足1x+1y=1n! 由于x,y>0,故显然有y>n! 不妨设y=n!+t(t>0),那么有 1x+1n!+t=1n! 化简后得到 n!(n!+t)+x(n!)=x(n!+t) x=(n!)2t+n! 故答案为d((n!)2) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #defin

BZOJ2721 [Violet 5]樱花

先令n! = a: 1 / x + 1 / y = 1 / a  =>  x = y * a / (y - a) 再令 k = y - a: 于是x = a + a ^ 2 / k  =>  k | a ^ 2 故等价于求a ^2的约数个数 素数筛一下什么的就好了嘛 1 /************************************************************** 2 Problem: 2721 3 User: rausen 4 Language: C++ 5

hdu 4542 数论 + 约数个数相关 腾讯编程马拉松复赛

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4542 小明系列故事--未知剩余系 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 889    Accepted Submission(s): 207 Problem Description "今有物不知其数,三三数之有二,五五数之有三,七七数之有

C语言 &#183; 约数个数

算法提高 约数个数 时间限制:1.0s   内存限制:512.0MB 输入一个正整数N,输出其约数的个数. 样例输入 12 样例输出 6 样例说明 12的约数包括:1,2,3,4,6,12.共6个. 1 #include<stdio.h> 2 int main(){ 3 int n; 4 int sum=0; 5 scanf("%d",&n); 6 if(n==0) return 0; 7 for(int i=1;i<=n/2;i++){ 8 if(n%i==

BZOJ 3994: [SDOI2015]约数个数和

3994: [SDOI2015]约数个数和 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 898  Solved: 619[Submit][Status][Discuss] Description 设d(x)为x的约数个数,给定N.M,求   Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Output T行,每行一个整数,表示你所求的答案. Sample Input 2 7

【线性筛】【筛法求素数】【约数个数定理】URAL - 2070 - Interesting Numbers

素数必然符合题意. 对于合数,如若它是某个素数x的k次方(k为某个素数y减去1),一定不符合题意.只需找出这些数. 由约数个数定理,其他合数一定符合题意. 就从小到大枚举素数,然后把它的素数-1次方都排除即可. #include<cstdio> #include<cmath> using namespace std; #define MAXP 1000100 #define EPS 0.00000001 typedef long long ll; ll L,R; bool isNo

hdu1492(约数个数定理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1492 这里先讲一下约数个数定理: 对于正整数x,将其质因分解为 x = pow(p1, a) * pow*(p2, b) * pow(p3, c) * ... 则其约数个数为:num(x) = (a+1) * (b+1) * (c+1) *... 推导: 由约数定义可知p1^a1的约数有:p1^0, p1^1, p1^2......p1^a1 ,共(a1+1)个;同理p2^a2的约数有(a2+1)个

算法:约数个数定理

约数个数定理的百度百科解释

算术基本定理 求一个数的约数个数

算术基本定理  求一个数的约数个数 算术基本定理: 分解素因数:n=(p1^k1)*(p2^k2)*...*(pn*kn).(分解方式唯一) n的约数个数为cnt(n)=(1+k1)*(1+k2)*...*(1+kn). bool isprime[maxn]; vector<int> prime; void play_prime() { memset(isprime,1,sizeof(isprime)); isprime[1]=0; for(int i=2;i<maxn;i++){ if