【区间筛】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<queue>
 8 #include<stack>
 9 #include<map>
10 #include<vector>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 const int maxn=1e6+3;
15 const ll mod=998244353;
16 ll l,r,k;
17 bool isprime[maxn];
18 int prime[maxn];
19 int cnt;
20 ll tot[maxn];
21 vector<int> s[maxn];
22 ll a[maxn];
23 void init()
24 {
25     memset(isprime,true,sizeof(isprime));
26     isprime[1]=false;
27     for(int i=2;i<maxn;i++)
28     {
29         if(isprime[i])
30         {
31             for(int k=2*i;k<maxn;k+=i)
32             {
33                 isprime[k]=false;
34             }
35         }
36     }
37     cnt=0;
38     for(int i=1;i<maxn;i++)
39     {
40         if(isprime[i])
41         {
42             prime[cnt++]=i;
43         }
44     }
45 }
46 ll fac(ll& num,ll p)
47 {
48     ll cou=0;
49     while(num%p==0)
50     {
51         cou++;
52         num/=p;
53     }
54     return cou;
55 }
56
57 int main()
58 {
59     init();
60     int T;
61     scanf("%d",&T);
62     while(T--)
63     {
64         scanf("%lld%lld%lld",&l,&r,&k);
65         for(int i=0;i<=r-l;i++)
66         {
67             a[i]=(ll)i+l;
68             tot[i]=1;
69         }
70         for(int i=0;i<cnt;i++)
71         {
72             if(prime[i]>r) break;
73             ll cou=l/(ll)prime[i];
74             if(l%(ll)prime[i]) cou++;
75             for(ll j=cou*(ll)prime[i];j<=r;j+=(ll)prime[i])
76             {
77                 int num=(int)(j-l);
78                 if(a[num]==1) continue;
79                 ll sum=fac(a[num],prime[i]);
80                 tot[num]=tot[num]*((k*sum)%mod+1)%mod;
81             }
82         }
83         ll ans;
84         if(l==1) ans=1;
85         else ans=0;
86         for(int i=0;i<=(int)(r-l);i++)
87         {
88             if(a[i]!=1) tot[i]=tot[i]*(k+1)%mod;
89             if(tot[i]!=1)
90             ans=(ans+tot[i])%mod;
91         }
92         cout<<ans<<endl;
93     }
94     return 0;
95 }

时间: 2024-11-03 03:25:11

【区间筛】2-17多校训练四 HDU6069 Counting Divisors的相关文章

HDU 4902 Nice boat 2014杭电多校训练赛第四场F题(线段树区间更新)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4902 解题报告:输入一个序列,然后有q次操作,操作有两种,第一种是把区间 (l,r) 变成x,第二种是把区间 (l,r) 中大于x的数跟 x 做gcd操作. 线段树区间更新的题目,每个节点保存一个最大和最小值,当该节点的最大值和最小值相等的时候表示这个区间所有的数字都是相同的,可以直接对这个区间进行1或2操作, 进行1操作时,当还没有到达要操作的区间但已经出现了节点的最大值跟最小值相等的情况时,说明

HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分)

HDU6621 K-th Closest Distance HDU2019多校训练第四场 1008(主席树+二分) 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6621 题意: 给你n个数,有m次询问 每次问你在区间[l,r]内 第k小的|\(a_i-p\)|是多少 题解: 主席树+二分 每次二分答案 如果p+mid到p-mid的值的个数大于k个的话,mid值就是可行了,然后缩小区间往左找即可 因为保证有解,所以二分出来的mid值就是答案了 que

【链表】2017多校训练3 HDU 6058 Kanade&#39;s sum

acm.hdu.edu.cn/showproblem.php?pid=6058 [题意] 给定一个排列,计算 [思路] 计算排列A中每个数的贡献,即对于每个ai,计算有ni个区间满足ai是区间中的第k大,那么ai对答案的贡献就是ai*ni 以ai为起点,统计ai右边离ai最近的,比ai大的k个数的位置 同理统计左边的位置,组合得到答案 关键是得到比ai大的离ai最近的k个数的位置 因为是排列,所以每个数都不相等,可以记录每个数的位置,然后从小到大枚举ai,这样维护一个双向链表,保证链表中的数就是

2016暑假多校训练参赛感想

参赛感想 这是第一次参加暑假多校训练,应该也会是人生中最后一次,我真的很庆幸能参加这个训练,和全国几乎所有高校的ACMer一起在一个平台上做题!昨天为止多校已经完全结束,今天看到叉姐的训练感想(叉姐的感想链接),我觉得我也有必要写下自己的训练感想. 人的眼界总是狭窄的,当在自己的学校站在前几名的时候觉得自己还不错,应该会有不错的将来,但是当第一次参加国赛(2015 南阳站)的时候我便被别人实力所震撼,我突然觉得自己在别人的眼里简直就是小学生,菜到不行.别人在5个小时可以AK,而我连最水的题也要想

多校训练hdu --Nice boat(线段树,都是泪)

Nice boat Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 47 Accepted Submission(s): 10 Problem Description There is an old country and the king fell in love with a devil. The devil always ask

2014多校训练九(HDU 4960 HDU 4961 HDU 4965 HDU 4968 HDU 4969 HDU 4970)

HDU 4960 Another OCD Patient 题意:给你一串数字  相邻x个数字合并成一个数字(相加)有一定代价  问  最少花费多少使得串变成回文串 思路: 读完题感觉像dp  数据范围也像  就开始想怎么表示状态  最简单的应该想到dp[i][j]表示i到j区间变成回文串的最小花费  状态想好了想做法  考虑将串分成AAAABBBBBBBCCC三段  即所有A合成一个数字  C也是  而且A和C相等  那么B串就变成了子问题  但是A和C是不是都要枚举呢?  这个串所有元素都是正

hdu 4902 Nice boat(2014多校训练第4场 1006)

Nice boat                                                                           Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description There is an old country and the king fell in love with a d

2014多校联合四(HDU 4901 HDU 4902 HDU 4905)

HDU 4901 The Romantic Hero 题意: 一串数字a  找一个位置分开  前面为S'后面为T'  从这两个集合中分别选出子集S和T  使得S中元素的"异或"值等于T中元素的"且"值  问一共几种方案 思路: 由于a[i]只有1024  那么无论怎么运算都不可能大于2047  又因为S和T有一个明显的分界  所以我们可以想到利用dp分左右两边处理  令l[i][j]表示从左到i位置且一定选取a[i]的情况下异或值为j的方案数  r[i][j]类似

2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)

题目链接 题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标.S中所有数按位异或后的值要与T中所有的数按位与的值相同,问能找出多少符合要求的组合. 思路 :比赛的时候有点没有头绪,后来二师兄想出了状态转移方程,YN又改了很多细节,最后才A的.总之是个别扭的DP..... 一开始是 _xor[i][j^a[i]] += _xor[i-1][j] :j 的下一个状态 就是异或上a[i],这个数组所代表的意思