HDU 6069 Counting Divisors(唯一分解定理+因子数)

http://acm.hdu.edu.cn/showproblem.php?pid=6069

题意:

思路:

根据唯一分解定理,$n={a_{1}}^{p1}*{a2_{}}^{p2}...*{a_{m}}^{pm}$,那么n的因子数就是

n的k次方也是一样的,也就是p前面乘个k就可以了。

先打个1e6范围的素数表,然后枚举每个素数,在[ l , r ]寻找该素数的倍数,将其分解质因数。

到最后如果一个数没有变成1,那就说明这个数是大于1e6的质数。(它就只有0和1两种选择)

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn=1e6+5;
17 const int mod=998244353;
18
19 int n;
20 int cnt=0;
21 int primes[maxn];
22 int vis[maxn];
23
24 void get_primes()
25 {
26     int m=sqrt(maxn+0.5);
27     for(int i=2;i<=m;i++)
28     {
29         if(!vis[i])
30         {
31             for(int j=i*i;j<=maxn;j+=i)
32                 vis[j]=1;
33         }
34     }
35     for(int i=2;i<=maxn;i++)
36         if(!vis[i])   primes[cnt++]=i;
37 }
38
39 ll l, r, k;
40 ll sum[maxn], num[maxn];
41
42 int main()
43 {
44     //freopen("in.txt","r",stdin);
45     get_primes();
46     int T;
47     scanf("%d",&T);
48     while(T--)
49     {
50         scanf("%lld%lld%lld",&l,&r,&k);
51
52         ll ans=0;
53         for(ll i=l;i<=r;i++)  {sum[i-l]=1;num[i-l]=i;}
54
55         for(int i=0; i<cnt && primes[i]*primes[i]<=r; i++)
56         {
57             ll tmp=ceil((long double)l/primes[i])*primes[i];
58             for(ll j=tmp;j<=r;j+=primes[i])
59             {
60                 if(num[j-l]%primes[i]==0)
61                 {
62                     int res=0;
63                     while(num[j-l]%primes[i]==0)
64                     {
65                         res++;
66                         num[j-l]/=primes[i];
67                     }
68                     sum[j-l]=(sum[j-l]*(((ll)res*k+1))%mod)%mod;
69                 }
70             }
71         }
72
73         for(ll i=l;i<=r;i++)
74         {
75             if(num[i-l]!=1)   sum[i-l]=(sum[i-l]*(k+1))%mod;  //大于1e6的质数
76             ans=(ans+sum[i-l])%mod;
77         }
78         printf("%lld\n",ans);
79     }
80     return 0;
81 }
时间: 2024-10-19 07:09:08

HDU 6069 Counting Divisors(唯一分解定理+因子数)的相关文章

HDU 6069 Counting Divisors —— 2017 Multi-University Training 4

Counting Divisors Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 2599    Accepted Submission(s): 959 Problem Description In mathematics, the function d(n) denotes the number of divisors of p

hdu 6069 Counting Divisors(求因子的个数)

Counting Divisors Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 3170    Accepted Submission(s): 1184 Problem Description In mathematics, the function d(n) denotes the number of divisors of

第四场 hdu 6069 Counting Divisors (逆向思维)

http://acm.hdu.edu.cn/showproblem.php?pid=6069 题目大意:求 i 从 l 到 r 中 i 的k次方的因子数之和. 解题思路:我们可以知道一个数有因子,则这个数的因子一定是若干个质数因子排列组合得到的.我们首先要得到10^6中的素数,然后它的因子数量是 相同质因子数量+1 的乘积,所以我们能够想到从 l 到 r 枚举每一个i得到其 相同质因子数量+1 的乘积 的累加和.但是这样在枚举时会发现有一些质数是并不是所求的 i 的因子,所以我们应该反过来考虑,

hdu 6069 Counting Divisors

题意:给出求L,R 之间的数的K次方的因子数之和 思路:打表求出1~10^6之间的素数,枚举[L,R]之间素数的倍数,然后按算数基本定理求出因子个数和.处理过后[L,R]之间的数要么是1,要么是一个素数,再次根据算数基本定理计算因子个数和. #include<bits/stdc++.h> #define MAXSIZE 1000015 #define INF 0x3f3f3f3f #define LL long long #define MOD 998244353 using namespac

HDU 6069 Counting Divisors(区间素数筛法)

题意:...就题面一句话 思路:比赛一看公式,就想到要用到约数个数定理 约数个数定理就是: 对于一个大于1正整数n可以分解质因数: 则n的正约数的个数就是 对于n^k其实就是每个因子的个数乘了一个K 然后现在就变成了求每个数的每个质因子有多少个,但是比赛的时候只想到sqrt(n)的分解方法,总复杂度爆炸,就一直没过去,然后赛后看官方题解感觉好妙啊! 通过类似素数筛法的方式,把L - R的质因子给分解,就可以在O(nlogn)的时间之内把所以的数给筛出来. 代码: /** @xigua */ #i

HDU 1452 Happy 2004(唯一分解定理)

题目链接:传送门 题意: 求2004^x的所有约数的和. 分析: 由唯一分解定理可知 x=p1^a1*p2^a2*...*pn^an 那么其约数和 sum = (p1^0+p1^1^-+p1^a1)*-* (pn^0+pn^1^-+pn ) 代码如下: #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; const

Counting Divisors HDU - 6069

Counting Divisors HDU - 6069 题意:给定区间[a,b]和k,求xk有多少因子(x属于[a,b]),求和. 题解:http://blog.csdn.net/zlh_hhhh/article/details/76680641 a.b最大可达到1e12,但是b-a<1e6. 一开始愚蠢的一个一个分解然后去求有多少因子然后求和,范围那么大裸裸的超时啊! 可以枚举素数,对每一个素数,把区间内所有可以分解的进行分解. 最后再求和. 1 #include <bits/stdc++

hdu 1215 求约数和 唯一分解定理的基本运用

http://acm.hdu.edu.cn/showproblem.php?pid=1215 题意:求解小于n的所有因子和 利用数论的唯一分解定理. 若n = p1^e1 * p2^e2 * --*pn^en(任何一个数都可以分解成素数乘积) 则n的因子个数为  (1+e1)(1+e2)--(1+en) n的各个因子的和为(1+p1+p1^2+--+p1^e1)(1+p2+p2^2+--+p2^e2)--(1+pn+pn^2+--+pn^en) (把式子化简就知道为什么了) ac代码: #inc

[ACM] HDU 3398 String (从坐标0,0走到m,n且不能与y=x-1相交的方法数,整数唯一分解定理)

String Problem Description Recently, lxhgww received a task : to generate strings contain '0's and '1's only, in which '0' appears exactly m times, '1' appears exactly n times. Also, any prefix string of it must satisfy the situation that the number