Hdu 6069 - Counting Divisors(区间筛质因子)
2017-08-04 15:52
309 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=6069
题目大意:
给定区间[l,r]和k,d(i)=∑d=1,d|nn1求式子∑i=lrd(ik)的值,结果对998244353取模
分析:
区间长度为1e6,数据有10组以上,暴力分解整个区间的话,每个数的分解至多是logn级别的,而基于Miller_Robin的质因数分解polard_rho也只是O(n14)级别的,远远达不到要求,所以不能从对每个数分解质因数上想,而是试着用[2,r√]内的所有质因子去筛[l,r]区间内的数,最后在除尽了这些因子后的数,要么是1,要么是一个大的质因子,且次数至多为1,因为如果大于sqrtr的因子次数大于1,这个数的大小就会大于r,产生矛盾
代码:
http://acm.hdu.edu.cn/showproblem.php?pid=6069
题目大意:
给定区间[l,r]和k,d(i)=∑d=1,d|nn1求式子∑i=lrd(ik)的值,结果对998244353取模
分析:
区间长度为1e6,数据有10组以上,暴力分解整个区间的话,每个数的分解至多是logn级别的,而基于Miller_Robin的质因数分解polard_rho也只是O(n14)级别的,远远达不到要求,所以不能从对每个数分解质因数上想,而是试着用[2,r√]内的所有质因子去筛[l,r]区间内的数,最后在除尽了这些因子后的数,要么是1,要么是一个大的质因子,且次数至多为1,因为如果大于sqrtr的因子次数大于1,这个数的大小就会大于r,产生矛盾
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod = 998244353; const int maxn = 1e6+100; ll l,r,k; int len; bool isprime[maxn+200]; int prime[maxn]; ll divi[maxn]; ll cnt[maxn]; void init() { for (int i =2 ; i <= maxn; i ++) { if (!isprime[i]) { prime[++prime[0]] = i; for (int j = i +i ; j <= maxn ; j+= i) isprime[j] = true; } } } void solve() { int st; for (int i = 1 ; prime[i]<= r/prime[i] && i<= prime[0] ; i ++) { //printf("i = %d\n",prime[i]); if (l%prime[i]==0) st = 1; else st = 1 + (prime[i]-l%prime[i]); for (int j = st ; j <= len ; j +=prime[i]) { int ct = 0; while (divi[j]%prime[i]==0) { divi[j]/=prime[i]; ct++; } cnt[j]*=(ct*k+1); if (cnt[j]>=mod) cnt[j] %= mod; } } ll ans = 0; for (int i =1 ; i <= len ; i ++) { if (divi[i]!=1) cnt[i] = cnt[i] * (k+1)%mod; //printf("divi[%d] = %lld\n",i,divi[i]); ans += cnt[i]; if (ans>=mod) ans %= mod; } printf("%lld\n",ans); } int main() { init(); //printf("prime[0] = %d\n",prime[0]); int T; scanf("%d",&T); while (T--) { scanf("%lld%lld%lld",&l,&r,&k); len = (int)(r- l +1); for (int i = 1 ; i <= len ; i ++) { divi[i] = l + i -1; cnt[i] = 1; } solve(); } return 0; }
相关文章推荐
- HDU 6069 Counting Divisors(区间素数筛法)
- (2017多校训练第四场)HDU - 6069 Counting Divisors 区间筛
- hdu 6069 区间筛
- [hdu 6069]素数筛+区间质因数分解
- HDU 6069 数学题,区间素数筛
- HDU-6069 Counting Divisors - 2017 Multi-University Training Contest - Team 4(分解质因子区间筛法)
- hdu 6069 Counting Divisors(区间筛)
- HDU 6069 Counting Divisors(枚举区间)(素数筛模版)
- HDU 6069 数论 区间素数筛(+赛后反思
- hdu 6069 Counting divisors 公式+区间筛
- HDU 6069 Counting Divisors【区间素筛】【经典题】【好题】
- hdu 6069 统计区间约数的个数 2017 Multi-University Training Contest - Team 4
- hdu 6069 区间筛
- Hdu 6069 Counting Divisors【素数区间筛+预处理素因子分解】
- HDU 6069 求区间[L,R]每个数的k次方的因子数之和
- hdu 1754 I Hate It (线段树--求区间最大值)(基础)
- HDU 4570(区间dp)
- hdu 5151 Sit sit sit(区间dp+排列组合)
- 树套树:二维线段树初步:hdu1823——Luck and Love(单点修改,区间查询)
- hdu 4348 To the moon(主席树,区间更新节省内存,经典)