专题班前缀和练习题 - A - 智乃酱的区间乘积

前缀积
要求Ai * A(i+1) * A(i+2) * ... * A(j)
只需要知道前缀积 B(j) 和 B(i-1),Ai * A(i+1) * A(i+2) * ... * A(j) = B(j) / B(i-1)
在取模的意义下
除法 = 乘法逆元

#include <bits/stdc++.h>
using namespace std;

typedef  long long ll;
const int maxn = 1e5 + 10;
const ll MOD = 1e9 + 7;
ll a[maxn], x;
int N, M;
int l, r;

ll pow_mod(ll x, ll n, ll mod){
    ll res = 1;
    while(n > 0){
        if(n & 1) res = res * x % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return res;
}

void extgcd(ll a,ll b,ll &d,ll &x,ll &y){
    if(!b){ d=a; x=1; y=0;}
    else{ extgcd(b,a%b,d,y,x); y-=x*(a/b); }
}
ll inverse(ll a,ll n){
    ll d,x,y;
    extgcd(a,n,d,x,y);
    return d==1?(x+n)%n:-1;
}

int main(){
    //freopen("input.txt", "r", stdin);
    scanf("%d%d", &N, &M);
    a[0] = 1;
    for(int i = 1; i <= N; i++){
        scanf("%lld", &x);
        a[i] = (a[i - 1] * x) % MOD;
    }
    while(M--){
        scanf("%d%d", &l, &r);
        //printf("%lld\n", a[r] * pow_mod(a[l - 1], MOD - 2, MOD) % MOD);
        printf("%lld\n", a[r] * inverse(a[l - 1], MOD) % MOD);
    }
    return 0;
}
全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务