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++.h>
 2 using namespace std;
 3 #define ll long long
 4 const int maxn=1e6+10;
 5 const int mod=998244353;
 6 int vis[maxn];
 7 int pri[maxn];
 8 ll ans[maxn],num[maxn];
 9 int cnt=0;
10 void init(){
11     cnt=0;
12     memset(vis,0,sizeof(vis));
13     for(ll i=2;i<maxn;i++){
14         if(!vis[i]){
15             pri[cnt++]=i;
16             for(ll j=i*i;j<maxn;j+=i)
17                 vis[j]=1;
18         }
19     }
20 }
21
22 int main(){
23     init();
24     int t;
25     scanf("%d",&t);
26     while(t--){
27         ll a,b,k;
28         scanf("%lld%lld%lld",&a,&b,&k);
29         int r=b-a+1;
30         for(int i=0;i<r;i++){
31             num[i]=i+a;
32             ans[i]=1;
33         }
34         for(int i=0;i<cnt;i++){
35             int x=pri[i];
36             ll s=(x-a%x)%x;  //!!
37             for(;s<r;s+=x){
38                 int temp=0;
39                 while(num[s]%x==0){
40                     temp++;
41                     num[s]/=x;
42                 }
43                 ans[s]*=(k*temp+1);
44                 if(ans[s]>=mod) ans[s]%=mod;
45             }
46         }
47         ll res=0;
48         for(int i=0;i<r;i++){
49             if(num[i]>1) ans[i]=ans[i]*(k+1)%mod;
50             res+=ans[i];
51             if(res>=mod) res-=mod;
52         }
53
54         printf("%d\n",res);
55     }
56 }

时间: 2024-08-02 06:57:33

Counting Divisors HDU - 6069的相关文章

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 Problem Description In mathematics, the function d(n) denotes the number of divisors of positive integer n. For example, d(12)=6 because 1,2,3,4,6,12 are all 12's divisors. In this problem, given l,r and k, your task is to calculate

第四场 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(唯一分解定理+因子数)

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 #includ

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

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

【区间筛】2-17多校训练四 HDU6069 Counting Divisors

http://acm.hdu.edu.cn/showproblem.php?pid=6069 [题意] 给定l,r,k,求 d(n)是n的因子个数 [思路] [Accepted] 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 #include

Counting Cliques HDU - 5952 单向边dfs

题目:题目链接 思路:这道题vj上Time limit:4000 ms,HDU上Time Limit: 8000/4000 MS (Java/Others),且不考虑oj测评机比现场赛慢很多,但10月5号的计蒜客重现赛只给了1000ms确实有点过分吧,好久没有做这种简单dfs做到自闭了,,,题目并不难,注意剪枝就好了,建图时建标号小的点指向标号大的点的单向边,这样按标号从小到大搜一遍就好了,完全图的任意两个点都要有边,按点的标号搜到第n-s+1个点,因为后面所有的点加起来都组不成点数为s的完全子