https://ac.nowcoder.com/acm/contest/19483/A

一个前缀积的问题,但是由于自己一开始不会逆元(数论0基础QAQ)自然在取模时出了错

于是先用线段树冲了一发

线段树:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+5,mod = 1e9+7;
int m,p;
int a[N];
struct Node{
    int l,r;
    long v;
}tr[N*4];
void pushup(int u){
    tr[u].v=(tr[u<<1].v*tr[u<<1|1].v)%mod;
}
void build(int u,int l, int r){
    tr[u]={l,r};
    if(l==r) {
        tr[u]={l,r,a[r]};
        return;
    }
    int mid=l+r>>1;
    build(u<<1,l,mid),build(u<<1|1,mid+1,r);
    pushup(u);
}
int query(int u,int l,int r){
    if(tr[u].l>=l &&tr[u].r<=r) return tr[u].v;
    int mid = tr[u].l + tr[u].r>>1;
    long v=1;
    if(l<=mid) v=query(u<<1,l,r);
    if(r>mid) v=(v*query(u<<1|1,l,r))%mod;
    return v;
}
int main(){
    int n=0,last=0;
    scanf("%d %d",&m,&p);
    for(int i=1;i<=m;i++){
        cin>>a[i];
    }
    build(1,1,m);
    int x,y;
    while(p--){
        scanf("%d %d",&x,&y);
        printf("%d\n",query(1,x,y)%mod);
    }
    return 0;
}

听了zngg的直播课之后理解了逆元,来简单解释一下:

逆元为什么会出现?

我们在取模时,可以发现,加减乘法,在取模之后在进行运算是不影响运算结果的

但是除法就会影响

数学家们显然是无法容忍这种局面,于是创造了“逆元”

我们在进行取模运算时,一个数n对应的模数有一个大小为n,从0开始的集合,称为其的

“完全剩余系”(如5的完全剩余系为0~4)

不在完全剩余系的数都能对应到一个完全剩余系的数

整数是,小数一样是,逆元运算就是将除数转化为其在完全剩余系中对应的数

使得除法的结果也符合取模运算的规则

具体的求证过程可以去参考专门的博客哒,我就不细写了!下面放代码

前缀积+乘法逆元

#include<bits/stdc++.h>
using namespace std;
const int N = 300005;
const long long mod = 1e9 + 7;
#define LL long long
LL quickpow(LL x, LL y, LL MOD){//快速幂,求逆元时使用
    LL bs = 1;
    while (y){
        if (y & 1) bs = (x * bs) % MOD;
        x = (x * x) % MOD;
        y >>= 1;
    }
    return bs;
}
LL get_inv(LL x){
    return quickpow(x, mod - 2, mod);//费马小定理求逆元
}
int n, l, r, m;
LL a[N], pre[N];
int main(){
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i){
        scanf("%lld", &a[i]);
    }
    pre[0] = 1;
    for (int i = 1; i <= n; ++i){
        pre[i] = pre[i - 1] * a[i] % mod;
    }
    while (m--){
        scanf("%d %d", &l, &r);
        printf("%lld\n", pre[r]*get_inv(pre[l - 1]) % mod);
        //用逆元代替除数然后取模,非常自然的得到结果
    }
    return 0;
}