博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【2017 Multi-University Training Contest - Team 4】Counting Divisors
阅读量:4670 次
发布时间:2019-06-09

本文共 2699 字,大约阅读时间需要 8 分钟。

Link:

Description

定义d(i)为数字i的因子个数;
rld(ik)
其中l,r<=1012rl<=106

Solution

如果把一个数x质因数分解成p1a1p2a2...pnan
的形式;
可知数字x的因子个数为
(a1+1)(a2+1)...(an+1)
因为i还有k次方;
所以答案就是
(a1k+1)(a2k+1)...(ank+1)
需要对l..r里面所有的数字都进行质因数分解;
可以这样
先处理出2..r之间的所有素数;
然后枚举每个素数i它在l..r之间的倍数x;
则对x 用素数i进行质因数分解,也即一直除它;
这样,就能算出来x在质因数分解的时候,素数i最后的指数是多少了;
(累乘数字x的答案就好);
记录x在进行质因数分解的时候被除剩下的数字,除的时候是用
这个记录的数字除;
最后这个数字可能会不变;
因为它本身可能就是一个素数;
所以小于r的素数可能不是它的因子;
但是不可能还有大于r的因子;
所以如果除剩下的数字还大于0;
答案再乘上(k+1)就好;
最后把每个数字它的答案累加起来;
(一开始可以用O(n)的素数筛求出1..n之间的所有素数);
NumberOf WA
many times
Reviw
一开始一直往O(n14)的质因数分解想了;
没想到这种方法.
判断出某个素数是某个数的因子之后,不要再记录它的因子是什么了;
直接就开始质因数分解,这样比较快;
不然会超时.
Code

#include 
using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define LL long long#define rep1(i,a,b) for (int i = a;i <= b;i++)#define rep2(i,a,b) for (int i = a;i >= b;i--)#define mp make_pair#define pb push_back#define fi first#define se second#define ms(x,y) memset(x,y,sizeof x)#define ri(x) scanf("%d",&x)#define rl(x) scanf("%lld",&x)#define rs(x) scanf("%s",x+1)#define oi(x) printf("%d",x)#define ol(x) printf("%lld",x)#define Open() freopen("F:\\rush.txt","r",stdin)#define Close() ios::sync_with_stdio(0)typedef pair
pii;typedef pair
pll;const int dx[9] = {
0,1,-1,0,0,-1,-1,1,1};const int dy[9] = {
0,0,0,-1,1,-1,1,-1,1};const double pi = acos(-1.0);const int N = 1e6;const LL MOD = 998244353;bool iszs[N+100];vector
zsb;LL num[N+100],ans[N+100];int main(){ //Open(); //Close(); ms(iszs,true); rep1(i,2,N) { if (iszs[i]) zsb.pb(i); int len = zsb.size(); rep1(j,0,len-1) { int t = zsb[j]; if (i*t>N) break; iszs[i*t] = false; if (i%t==0) break; } } int T; ri(T); while (T--){ LL l,r,k; rl(l),rl(r),rl(k); for (LL i = l;i <= r;i++) num[i-l+1] = i,ans[i-l+1] = 1; rep1(i,0,(int) zsb.size()-1){ LL x = zsb[i]; if (x > r) break; LL temp = ((l-1)/x + 1)*x; for (LL i = temp;i <= r;i+=x){ LL tot = i,cnt = 0; while (tot%x==0){ tot/=x; num[i-l+1]/=x; cnt++; } ans[i-l+1] = ans[i-l+1]*(cnt*k+1)%MOD; } } LL fans = 0; for (LL i = l;i <= r;i++){ if (num[i-l+1]!=1){ fans = (fans + ans[i-l+1]*(k+1)%MOD)%MOD; }else fans = (fans + ans[i-l+1])%MOD; } ol(fans);puts(""); } return 0;}

转载于:https://www.cnblogs.com/AWCXV/p/7626139.html

你可能感兴趣的文章
java定时任务调度工具
查看>>
[POI2004]GRA
查看>>
ES之各种运算符,for、while、do while 、switch case循环
查看>>
Twisted
查看>>
python-day34--进程补充
查看>>
POJ 1001 Exponentiation
查看>>
Redhat之package管理--学点 YUM和RPM
查看>>
使用Bochs调试Linux kernel 随笔 -- 准备
查看>>
Ajax 密码验证
查看>>
idea的项目结构
查看>>
stl pair
查看>>
python路径相关小问题
查看>>
老李分享:持续集成学好jenkins之Git和Maven配置
查看>>
Android深度探索-卷1第二章心得体会
查看>>
linux中cat、more、less命令区别详解
查看>>
java读写文件总结
查看>>
阿里题目:明星群众问题
查看>>
为什么SQL用UPDATE语句更新时更新行数会多3行有触发器有触发器有触发器有触发器有触发器有触发器...
查看>>
关于hist
查看>>
Xtrareport 交叉报表
查看>>