不算很难的一道题

原题的数据虽然很小,但是我们不能欺负它,我们就要当$S[i] \leqslant 10^9$来做这题

最小公倍数 = 所有的质因数取可能的最大幂相乘

对于$> \sqrt S$的质数,幂只会为$0$或者$1$,只要维护有没有存在即可

对于$< \sqrt S$的质数,在$S[i] \leqslant 50000$时,我们可以暴力对每个质数维护相应地幂次

但是在$S[i] \leqslant 10^9$时,我们考虑把$p, p^2, p^3, ....$单独看做一种质数,每种质数都有$p$的贡献来维护

由于删除操作不好做,因此考虑离线扫描线做到只有插入

左端点从右到左扫,只要维护右端点的答案即可

可以发现,每种质数出现的区间一定是一段后缀,因此可以考虑维护后缀积来快速回答

每次扫描线加入点时,只要分解这个点,然后把相应地质数的后缀积改变即可

如果$S[i] \leqslant 50000$,那么复杂度可以做到$O(n \log^2 n + q \log n)$

否则,复杂度可以做到$O(n v(n) + n \log^2 n + q \log n)$,其中$v(n)$为分解$n$的复杂度

#include <map>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; extern inline char gc() {
static char RR[], *S = RR + , *T = RR + ;
if(S == T) fread(RR, , , stdin), S = RR;
return *S ++;
}
inline int read() {
int p = , w = ; char c = gc();
while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
while(c >= '' && c <= '') p = p * + c - '', c = gc();
return p * w;
} #define ri register int
#define sid 50005
const int mod = ; int n, Q;
int v[sid], ans[sid];
struct Ask {
int l, r, id;
friend bool operator < (Ask a, Ask b)
{ return a.l > b.l; }
} q[sid]; int inv[sid], pre[sid];
int nop[sid], pr[sid], mp[sid], tot;
void Sieve() {
for(ri i = ; i <= ; i ++) {
if(!nop[i]) pr[++ tot] = i, mp[i] = i;
for(ri j = ; j <= tot; j ++) {
int p = i * pr[j]; if(p > ) break;
nop[p] = ; mp[p] = pr[j];
if(i % pr[j] == ) break;
}
}
inv[] = ;
for(ri i = ; i <= ; i ++)
inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
} int val[sid << ]; #define ls (o << 1)
#define rs (o << 1 | 1)
inline void inh(int o) { val[o] = 1ll * val[ls] * val[rs] % mod; } void build(int o, int l, int r) {
val[o] = ; if(l == r) return;
int mid = (l + r) >> ;
build(ls, l, mid); build(rs, mid + , r);
} void upd(int o, int l, int r, int p, int v, int opt) {
if(l == r) {
if(opt == ) val[o] = 1ll * val[o] * v % mod;
else val[o] = 1ll * val[o] * inv[v] % mod;
return;
}
int mid = (l + r) >> ;
if(p <= mid) upd(ls, l, mid, p, v, opt);
else upd(rs, mid + , r, p, v, opt);
inh(o);
} int qry(int o, int l, int r, int ml, int mr) {
if(ml > r || mr < l) return ;
if(ml <= l && mr >= r) return val[o];
int mid = (l + r) >> ;
return 1ll * qry(ls, l, mid, ml, mr) * qry(rs, mid + , r, ml, mr) % mod;
} void solve(int v, int c, int now) {
if(!v) return; int w = ;
for(ri i = ; i <= c; i ++) {
w = w * v;
if(pre[w]) upd(, , n, pre[w], v, -);
upd(, , n, now, v, ); pre[w] = now;
}
} void add(int o) {
int w = v[o], lstp = , cnt = ;
while() {
if(mp[w] != lstp)
solve(lstp, cnt, o), lstp = mp[w], cnt = ;
else cnt ++;
if(w == ) break; w /= mp[w];
}
} int main() { n = read(); Q = read(); Sieve();
for(ri i = ; i <= n; i ++) v[i] = read(); for(ri i = ; i <= Q; i ++)
q[i].id = i, q[i].l = read(), q[i].r = read();
sort(q + , q + Q + ); build(, , n);
for(ri i = n, j = ; i >= ; i --) {
add(i);
while(q[j].l == i && j <= Q)
ans[q[j].id] = qry(, , n, i, q[j].r), j ++;
} for(ri i = ; i <= Q; i ++) printf("%d\n", ans[i]);
return ;
}

51nod1203 JZPLCM 线段树 + 扫描线的更多相关文章

  1. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  2. Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)

    题目链接:http://codeforces.com/contest/522/problem/D 题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...

  3. 【POJ-2482】Stars in your window 线段树 + 扫描线

    Stars in Your Window Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11706   Accepted:  ...

  4. HDU 4419 Colourful Rectangle --离散化+线段树扫描线

    题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...

  5. BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤

    3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...

  6. BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞

    看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...

  7. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  8. POJ1151+线段树+扫描线

    /* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...

  9. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

随机推荐

  1. [php]php错误处理机制

    1.判断文件是否存在,file_exists("文件名") or die("no such file");2.set_error_hanlder("错 ...

  2. 【BZOJ】1297: [SCOI2009]迷路

    [题意]给定n个点的有向带边权图,求0到n-1长度恰好为T的路径数.n<=10,T<=10^9,边权1<=wi<=9. [算法]矩阵快速幂 [题解]这道题的边权全部为1时,有简 ...

  3. Dull Chocolates Gym - 101991D 离散化 前缀和

    题目链接:https://vjudge.net/problem/Gym-101991D 具体思路:首先看数据范围,暴力肯定不可以,可以下离散化,然后先求出离散化后每一个点到(1,1)的符合题目的要求的 ...

  4. django框架之中间件

    中间件简介 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 在djang ...

  5. 去除\ufeff的解决方法,python语言

    语言:python 编程工具:pycharm 硬件环境:win10 64位 读取文件过程中发现一个问题:已有记事本文件(非空),转码 UTF-8,复制到pycharm中,在开始位置打印结果会出现  \ ...

  6. for 、forEach 、 forof、 forin遍历对比

    一.遍历内容的异同 1.for 和 for...in 是针对数组下标的遍历 2.forEach 及 for...of 遍历的是数组中的元素 二.对非数字下标的处理 由于array在js中也是对象中的一 ...

  7. redis的备份恢复

    说明:默认rdb方式保存,redis支持主从和哨兵等,但是在某些情况下我们会单机跑,所以有时候我们就会需要设计到备份恢复 环境:原始redis:192.168.1.200 新redis:192.168 ...

  8. Dev Express 安装

    Dev Express 安装 点击DevExpressUniversalTrialComplete-20151209.exe开始安装 选择需要安装的产品   选择需要安装的产品目录,这里设置为D盘 开 ...

  9. 斐讯路由器L(联)B(壁)K-码兑换包安全下车通道(图文教程)

    大家好,最近大家比较关心的斐讯路由器如何下车问题,楼主亲自试提取了一遍,记录下过程,欢迎大家一起讨论. 言归正传,上图,上图! No.1 打开斐讯提供的良心k码退换通道: https://tech-s ...

  10. BootStrap的栅格系统的基本写法(布局)

    代码如下: <!DOCTYPE html> <html> <head> <title>BootStrap的基础入门</title> < ...