51nod1203 JZPLCM 线段树 + 扫描线

不算很难的一道题
原题的数据虽然很小,但是我们不能欺负它,我们就要当$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 线段树 + 扫描线的更多相关文章
- 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)
D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- 【POJ-2482】Stars in your window 线段树 + 扫描线
Stars in Your Window Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11706 Accepted: ...
- HDU 4419 Colourful Rectangle --离散化+线段树扫描线
题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...
- BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤
3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...
- BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞
看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...
- hdu 5091(线段树+扫描线)
上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...
- POJ1151+线段树+扫描线
/* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
随机推荐
- TED_Topic2:My desperate journey with a human smuggler
My desperate journey with a human smuggler By Barat Ali Batoor When I was a child there was a toy wh ...
- array_unique() 去重复
array_unique() 定义和用法 array_unique() 函数移除数组中的重复的值,并返回结果数组. 当几个数组元素的值相等时,只保留第一个元素,其他的元素被删除. 返回的数组中键名不变 ...
- Tensorflow中使用TFRecords高效读取数据--结合Attention-over-Attention Neural Network for Reading Comprehension
原文链接:https://arxiv.org/pdf/1607.04423.pdf 本片论文主要讲了Attention Model在完形填空类的阅读理解上的应用. 转载:https://blog.cs ...
- 64_r3
rubygem-resque-cleaner-0.3.0-5.fc24.noarch.rpm 24-Sep-2016 22:26 22422 rubygem-resque-cleaner-doc-0. ...
- 5.Longest Palindromic Substring---dp
题目链接:https://leetcode.com/problems/longest-palindromic-substring/description/ 题目大意:找出最长回文子字符串(连续). 法 ...
- Zabbix3.0 API调用
Zabbix API 是什么? API简单来说是服务对外开放的一个接口,用户通过该接口传递请求,完成操作.API的背后是一组方法的集合,这些方法实现了服务对应的不同功能,调用API实际上就是换了一种方 ...
- 如何将qlv格式的腾讯视频转换为mp4格式
一般来说,每个视频网站都会有自己的视频播放格式,如优酷的KUX.爱奇艺的QSV和腾讯的QLV等. 但是大家知道,优酷是有转码功能的,而就目前来说腾讯视频还没有转码功能,下面是将qlv格式的腾讯视频转换 ...
- mongodb与mysql传统的关系数据库区别
转自:易百教程 MongoDB中的数据具有灵活的模式.文档在同一集合,但它们不需要具有相同的字段或结构集合,集合文档中的公共字段可以包含不同类型的数据. MongoDB中的数据具有灵活的模式.与SQL ...
- spring源码分析---IOC(1)
我们都知道spring有2个最重要的概念,IOC(控制反转)和AOP(依赖注入).今天我就分享一下spring源码的IOC. IOC的定义:直观的来说,就是由spring来负责控制对象的生命周期和对象 ...
- 三十分钟理解计算图上的微积分:Backpropagation,反向微分
神经网络的训练算法,目前基本上是以Backpropagation (BP) 反向传播为主(加上一些变化),NN的训练是在1986年被提出,但实际上,BP 已经在不同领域中被重复发明了数十次了(参见 G ...