D. REQ
题意:
给出一段序列,给出询问,求l, r区间里面的数相乘的数欧拉函数
首先,欧拉函数, n已经维护好了,到时候求个逆元即可,然后如果能知道l, r区间里面的质数即可,这个可以利用树状数组前缀积的形式,先对所有的区间按r升序,然后离线处理,l = 0开始,然后对于每一个数,如果已经分解的质数已经被处理过了,那就在当前的位置乘以反向的,这样会消除对后面的影响,没有的话就直接,等等,现在只知道一个效果,就是能够维护维护前缀积
点击查看代码
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);
#define endl '\n'
using namespace std;
typedef long long ll;
const ll MAXN = 1e6 + 10;
const ll MOD = 1e9 + 7;
ll n, q;
ll a[MAXN], fa[MAXN], prime[MAXN], mul[MAXN], ans[MAXN], treea[MAXN];
bool vis[MAXN];
struct Node
{
ll l, r, id;
} seg[MAXN];
bool comp(Node x, Node y)
{
if (x.r == y.r)
return x.l < y.l;
return x.r < y.r;
}
//线性筛
void get_prime()
{
int tot = 0;
for (int i = 2; i < MAXN; ++i)
{
if (!vis[i])
prime[++tot] = i, fa[i] = i;
for (int j = 1; j <= tot && i * prime[j] < MAXN; ++j)
{
vis[i * prime[j]] = true, fa[i * prime[j]] = prime[j];
if (i % prime[j] == 0)
break;
}
}
}
ll quick_pow(ll base, ll power)
{
ll ans = 1;
while (power)
{
if (power & 1)
ans = ans * base % MOD;
base = base * base % MOD;
power >>= 1;
}
return ans;
}
void add(ll p, ll x)
{
for (int i = p; i < MAXN; i += i & (-i))
treea[i] = treea[i] * x % MOD;
}
ll query(ll p)
{
ll ans = 1;
for (int i = p; i; i -= i & (-i))
ans = ans * treea[i] % MOD;
return ans;
}
int last[MAXN];
void update(ll i)
{
for (int x = a[i], p = fa[x]; x > 1; p = fa[x])
{
add(i, p - 1), add(i, quick_pow(p, MOD - 2));
if (last[p])
add(last[p], p), add(last[p], quick_pow(p - 1, MOD - 2));
last[p] = i;
while (x % p == 0)
x /= p;
}
}
int main()
{
IOS; cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i)
cin >> a[i];
cin >> q;
for (int i = 1, l, r; i <= q; ++i)
cin >> seg[i].l >> seg[i].r, seg[i].id = i;
sort(seg + 1, seg + 1 + q, comp);
get_prime();
mul[0] = 1;
for (int i = 1; i <= n; ++i)
mul[i] = mul[i - 1] * a[i] % MOD, treea[i] = 1;
int l = 0;
for (int i = 1; i <= q; ++i)
{
while (l < seg[i].r)
update(++l);
ans[seg[i].id] = mul[seg[i].r] % MOD * quick_pow(mul[seg[i].l - 1], MOD - 2) % MOD * query(seg[i].r) % MOD * quick_pow(query(seg[i].l - 1), MOD - 2) % MOD;
}
for (int i = 1; i <= q; ++i)
cout << ans[i] % MOD << endl;
return 0;
}
/*
1
560149
1
1 1
*/
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程