题目链接:洛谷

这个跟上上个Ynoi题目是一样的套路,首先我们知道\(n=\prod p_i^{\alpha_i}\)时\(d(n)=\prod (\alpha_i+1)\)。

首先对所有数分解质因数,首先预处理\(\leq \sqrt{\max a_i}\)的所有质数,然后一个一个试除,时间复杂度\(O(\frac{n\sqrt{a_i}}{\log{a_i}})\),在lxl的数据下跑得飞快(大家都知道,卡常是要看数据性质的)。或者使用Pollard-rho分解也是可以的。

然后莫队,维护\([l,r]\)的乘积的所有质因子的指数和对应的答案,用hashmap维护,注意每个数至多有10个质因子,所以时间复杂度为\(O(10n\sqrt{n})\)还常数巨大,你人没了。

首先,我们先预处理\([1,i]\)的乘积中前168个质数(\(\leq 1000\)的质数)的指数,询问的时候直接查询前缀和就可以单独处理了,之后至多剩下两个质因子,对这些质因子离散化之后开桶莫队。要处理当前答案还需要预处理逆元。

时间复杂度\(O(mod+\frac{n\sqrt{a_i}}{\log a_i}+168n+2n\sqrt{n})\)

#include<bits/stdc++.h>
#define Rint register int
using namespace std;
typedef long long LL;
const int N = 100003, M = 31630, mod = 19260817;
int n, m, blo, a[N], pri[M], tot, s[N][168], inv[mod], ans[N];
bool notp[M];
inline void init(int m){
notp[0] = notp[1] = true;
for(Rint i = 2;i <= m;i ++){
if(!notp[i]) pri[tot ++] = i;
for(Rint j = 0;j < tot && i * pri[j] <= m;j ++){
notp[i * pri[j]] = true;
if(!(i % pri[j])) break;
}
}
}
int len, val[2 * N], cnt[2 * N], fac[N][2], ql = 1, qr = 0, qans = 1;
struct Query {
int l, r, id;
inline bool operator < (const Query &o) const {
if(l / blo != o.l / blo) return l / blo < o.l / blo;
if(l / blo & 1) return r > o.r;
return r < o.r;
}
} q[N];
inline void _add(int x){
++ cnt[x];
qans = (LL) qans * inv[cnt[x]] % mod * (cnt[x] + 1) % mod;
}
inline void _del(int x){
qans = (LL) qans * inv[cnt[x] + 1] % mod * cnt[x] % mod;
-- cnt[x];
}
inline void add(int x){
for(Rint j = 0;j < 2;j ++) if(fac[x][j]) _add(fac[x][j]);
}
inline void del(int x){
for(Rint j = 0;j < 2;j ++) if(fac[x][j]) _del(fac[x][j]);
}
int main(){
scanf("%d%d", &n, &m); init(31629); blo = sqrt(n);
for(Rint i = 1;i <= n;i ++) scanf("%d", a + i);
for(Rint i = 1;i <= n;i ++){
for(Rint j = 0;j < 168;j ++){
s[i][j] = s[i - 1][j];
while(!(a[i] % pri[j])) a[i] /= pri[j], ++ s[i][j];
}
if(a[i] == 1) continue;
for(Rint j = 168;j < tot;j ++)
if(!(a[i] % pri[j])){
fac[i][0] = pri[j];
if(a[i] > pri[j]) fac[i][1] = a[i] / pri[j]; break;
}
if(!fac[i][0]) fac[i][0] = a[i];
for(Rint j = 0;j < 2;j ++) if(fac[i][j]) val[++ len] = fac[i][j];
}
inv[1] = 1;
for(Rint i = 2;i < mod;i ++) inv[i] = mod - (LL) mod / i * inv[mod % i] % mod;
sort(val + 1, val + len + 1);
len = unique(val + 1, val + len + 1) - val - 1;
for(Rint i = 1;i <= n;i ++)
for(Rint j = 0;j < 2;j ++)//{
if(fac[i][j]) fac[i][j] = lower_bound(val + 1, val + len + 1, fac[i][j]) - val;
// printf("fac[%d][%d] = %d\n", i, j, fac[i][j]);
// }
for(Rint i = 1;i <= m;i ++) scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i;
sort(q + 1, q + m + 1);
for(Rint i = 1;i <= m;i ++){
while(ql > q[i].l) add(-- ql);
while(qr < q[i].r) add(++ qr);
while(ql < q[i].l) del(ql ++);
while(qr > q[i].r) del(qr --);
// printf("ql = %d, qr = %d, qans = %d\n", ql, qr, qans);
int tmp = qans;
for(Rint j = 0;j < 168;j ++)
tmp = (LL) tmp * (s[q[i].r][j] - s[q[i].l - 1][j] + 1) % mod;
ans[q[i].id] = tmp;
}
for(Rint i = 1;i <= m;i ++) printf("%d\n", ans[i]);
}

Luogu5071 [Ynoi2015]此时此刻的光辉 【莫队】的更多相关文章

  1. [Ynoi2015]此时此刻的光辉(莫队)

    一道神题...自己写出来以后被卡常了...荣获洛谷最差解... 思路还是比较好想,对于每个数 \(\sqrt{n}\) 分块,对于 \(\sqrt{n}\) 以内的数,我们可以直接求出来.对于 \(\ ...

  2. 洛谷 P5071 - [Ynoi2015] 此时此刻的光辉(莫队)

    洛谷题面传送门 一道其实算得上常规的题,写这篇题解是为了总结一些数论中轻微(?)优化复杂度的技巧. 首先感性理解可以发现该问题强于区间数颜色问题,无法用常用的 log 数据结构维护,因此考虑分块/莫队 ...

  3. [Ynoi2015]此时此刻的光辉

    题目大意: 给定一个序列,每次询问一段区间的数的乘积的约数个数. 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐 ...

  4. 【题解】Luogu P5071 [Ynoi2015]此时此刻的光辉

    众所周知lxl是个毒瘤,Ynoi道道都是神仙题,题面好评 原题传送门 一看这题没有修改操作就知道这是莫队题(我也只会莫队) 我博客里对莫队的简单介绍 一个数N可以分解成\(p_1^{c_1}p_2^{ ...

  5. P5071 [Ynoi2015]此时此刻的光辉

    传送门 lxl大毒瘤 首先一个数的因子个数就是这个数的每个质因子的次数+1的积,然后考虑把每个数分解质因子,用莫队维护,然后我交上去就0分了 如果是上面那样的话,我们每一次移动指针的时间复杂度是O(这 ...

  6. 洛谷P5072 [Ynoi2015]盼君勿忘 [莫队]

    传送门 辣鸡卡常题目浪费我一下午-- 思路 显然是一道莫队. 假设区间长度为\(len\),\(x\)的出现次数为\(k\),那么\(x\)的贡献就是\(x(2^{len-k}(2^k-1))\),即 ...

  7. 【洛谷5072】[Ynoi2015] 盼君勿忘(莫队)

    点此看题面 大致题意: 一个序列,每次询问一个区间\([l,r]\)并给出一个模数\(p\),求模\(p\)意义下区间\([l,r]\)内所有子序列去重后值的和. 题意转化 原来的题意看起来似乎很棘手 ...

  8. Luogu5072 [Ynoi2015]盼君勿忘 【莫队】

    题目描述:对于一个长度为\(n\)的序列,\(m\)次询问\(l,r,p\),计算\([l,r]\)的所有子序列的不同数之和\(\mathrm{mod} \ p\). 数据范围:\(n,m,a_i\l ...

  9. BZOJ 3289: Mato的文件管理[莫队算法 树状数组]

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2399  Solved: 988[Submit][Status][Di ...

随机推荐

  1. [PKUSC2018]主斗地(搜索+贪心)

    首先如果对子和三张牌出现在解中,那么全拆成单张显然没有问题,顺子同理.于是真正有用的牌型就只有单牌.三带一.三带二.四带二了. 暴搜jry手中的牌,然后先搜出双方的大牌型(即三张.四张牌的个数),再枚 ...

  2. 服务篇:我的第一WebService应用

    一.我的第一个Webservice应用 1.新建一个空项目 2.添加新项,加入asmx,并再浏览器浏览 3.添加一个aspx网页 4.右键引用→添加服务引用→高级→添加Web引用,输入再浏览器浏览的a ...

  3. git版本控制系统重新认识

    git 版本控制系统 目标:完全搞懂git分布式版本控制系统 搭建git版本控制系统 cvs集中化版本控制系统--集中式管理的服务器 git分布式版本控制系统--会将原始代码仓库镜像下来 新项目使用g ...

  4. linux 命令行 光标移动技巧等

    看一个真正的专家操作命令行绝对是一种很好的体验-光标在单词之间来回穿梭,命令行不同的滚动.在这里强烈建立适应GUI节目的开发者尝试一下在提示符下面工作.但是事情也不是那么简单,还是需要知道“如何去做” ...

  5. 【转载】Intellij IDEA神器居然还有这些小技巧

    概述Intellij IDEA真是越用越觉得它强大,它总是在我们写代码的时候,不时给我们来个小惊喜.出于对Intellij IDEA的喜爱,我决定写一个与其相关的专栏或者系列,把一些好用的Intell ...

  6. S3C2440 块设备(待续)

    1.块设备只能以块为单位接受输入和返回输出,而字符设备则以字节为单位 2.块设备对于I/O请求有对应的缓冲区,因此他们可以选择以什么顺序进行响应,字符设备无须缓冲且被直接读写.对于存储设备而言调整读写 ...

  7. sql server存储过程解密

    解密存储过程: USE [RYTreasureDB] GO /****** Object: StoredProcedure [dbo].[sp__windbi$decrypt] Script Date ...

  8. TLS握手秘钥套件分析

    1.为了弄清楚TLS1.3的内部结构,觉得有必要将TLS的整个结构从新整理一遍,方便后续在做握手协议的形式化分析的时候能够不遗漏每个加密和认证的的环节. TLS1.3不论文在协议内容上还是性能上都较之 ...

  9. linux安装zookeeper,安装zkui,zookeeper可视化

    系统要求 支持的平台 ZooKeeper由多个组件组成.某些组件得到广泛支持,其他组件仅在较小的平台上受支持. 客户端是Java客户端库,应用程序使用它连接到ZooKeeper集合. Server是在 ...

  10. spark 实现多文件输出

    需求 不同的key输出到不同的文件 txt文件 multiple.txt 中国;22 美国;4342 中国;123 日本;44 日本;6 美国;55 美国;43765 日本;786 日本;55 sca ...