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代表该区 ...
随机推荐
- vue-router.esm.js?fe87:16 [vue-router] Route with name 'page' does not exist
本文地址:http://www.cnblogs.com/veinyin/p/7910525.html 我的路由配置 { path: '/page', name: page, component: pa ...
- SDUT 3917
UMR 现在手里有 n 张康纳的表情,最上面一张是玛吉呀巴库乃.现在 UMR 如果每次把最上面的 m 张牌移到最下面而不改变他们的顺序及朝向,那么至少经过多少次移动玛吉呀巴库乃才会又出现在最上面呢? ...
- unity3d 资源文件从MAX或者MAYA中导出的注意事项
unity3d 资源文件从MAX或者MAYA中导出的注意事项 1.首先,Unity3d 中,导出带动画的资源有2种导出方式可以选择: 1) 导出资源时,只导出一个文件,保留模型,骨骼和所 ...
- F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解
题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...
- Arm-kernel 内存收集【转】
转自:http://blog.csdn.net/linyt/article/details/6627664 Linux kernel的内存管理子系统非常复杂,为了深入了解内存管理系统,我打算分多篇文章 ...
- Ubuntu 17.10 用 apt 搭建 lamp 环境(精简版)
这篇文章主要用来快速部署以 php 5.6 为主的 lamp 环境,要看详细安装包括虚拟主机配置的请参考这篇:http://www.cnblogs.com/mingc/p/7864030.html 一 ...
- Appium 1.6.3使用的自动化测试引擎
automationName项的值: Appium:默认值. Selendroid:安卓2.3(API 9)-4.1(API 16)版本使用. UiAutomator2:最新安卓版本. XCUITes ...
- 在rhel7上搭建centos7的yum源
1. 再查看现在主机上的yum源,并将它们删除 [root@localhost ~]# rpm -qa|grep yum | xargs rpm -e --nodeps # --nodeps 不管有没 ...
- cgi与html相互调用
html中调用cgi.<form action="/cgi-bin/mult.cgi" method="get" target="_blank& ...
- bind1st bind2nd的使用
STL中的函数 bind1st. bind2nd用于将一个二元算子转换成一元算子,需要两个 参数,要转换的bf和一个值v. 参考:http://blog.csdn.net/simahao/articl ...