REQ

把询问离线, 我们从n 到 1遍历过去的时候, 把(1 - 1 / p)乘在最靠近当前位置的地方, 然后区间求乘积就好啦。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long
using namespace std; const int N = 1e6 + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-; struct SegmentTree {
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
int a[N << ];
void build(int *b, int l, int r, int rt) {
if(l == r) {
a[rt] = b[l];
return;
}
int mid = l + r >> ;
build(b, lson); build(b, rson);
a[rt] = 1ll * a[rt << ] * a[rt << | ] % mod;
}
void update(int p, int val, int l, int r, int rt) {
if(l == r) {
a[rt] = 1ll * a[rt] * val % mod;
return;
}
int mid = l + r >> ;
if(p <= mid) update(p, val, lson);
else update(p, val, rson);
a[rt] = 1ll * a[rt << ] * a[rt << | ] % mod;
}
int query(int L, int R, int l, int r, int rt) {
if(l >= L && r <= R) return a[rt];
int mid = l + r >> ;
if(R <= mid) return query(L, R, lson);
else if(L > mid) return query(L, R, rson);
else return (1ll * query(L, R, lson) * query(L, R, rson)) % mod;
}
}; int n, q, a[N], mul[N], del[N], ans[N], Map[N];
vector<int> prime;
vector<int> fac[N];
vector<PII> qus[N];
SegmentTree seg;
int Power(int a, int b) {
int ans = ;
while(b) {
if(b & ) ans = 1ll * ans * a % mod;
a = 1ll * a * a % mod; b >>= ;
}
return ans;
} int main() {
for(int i = ; i < N; i++) {
if(SZ(fac[i])) continue;
prime.push_back(i);
for(int j = i; j < N; j += i)
fac[j].push_back(i);
}
for(auto& x : prime) {
mul[x] = ( - Power(x, mod - ) + mod) % mod;
del[x] = Power(mul[x], mod - );
}
scanf("%d", &n);
for(int i = ; i <= n; i++) scanf("%d", &a[i]);
seg.build(a, , n, );
scanf("%d", &q);
for(int i = ; i <= q; i++) {
int L, R; scanf("%d%d", &L, &R);
qus[L].push_back(mk(R, i));
}
for(int i = n; i >= ; i--) {
for(auto& t : fac[a[i]]) {
if(Map[t]) seg.update(Map[t], del[t], , n, );
seg.update(i, mul[t], , n, );
Map[t] = i;
}
for(auto& t : qus[i]) {
ans[t.se] = seg.query(i, t.fi, , n, );
}
}
for(int i = ; i <= q; i++) printf("%d\n", ans[i]);
return ;
} /*
*/

最新文章

  1. c#获取ip的方法cdn加速获取真实ip方法
  2. 解决SQL server 2014 修改表中的字段,无法保存的问题。
  3. setTimeout 导致的浏览器假死
  4. 【javascript】 for循环小技巧
  5. java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.TextView
  6. 【ufldl tutorial】Softmax Regression
  7. Asp.net内置对象之Request对象(概述及应用)
  8. chrome下的js调试
  9. java_字符
  10. 从一个SVN下载的导入另一个SVN里面
  11. Android ADT安装时卡在Calculating requirements and dependencies
  12. android国际化
  13. vue客户端渲染首屏优化之道
  14. 利用jquery-barcode.js实现生成条形码
  15. 音视频下载Chrome插件 官方主页
  16. c/c++叉树的创建与遍历(非递归遍历左右中,不破坏树结构)
  17. checkbox jquery操作总结
  18. python的os模块总结
  19. Iris Classification on Tensorflow
  20. k8s的内置DNS增加父系DNS方法

热门文章

  1. web@HTML常用标签分类,标签嵌套规则
  2. 随机函数rand()和srand()
  3. 基于数组的循环队列(C++模板实现)
  4. Laravel 5.2问题-----postman进api的post请求,为什么出现Forbidden?
  5. Django 笔记(六)mysql增删改查
  6. Android应用开发中三种常见的图片压缩方法
  7. 自定义你的 Confluence 6 站点
  8. Confluence 6 管理插件和组件
  9. 扇形多级菜单可配置Demo
  10. mysql数据库之基本操作和存储引擎