智乃酱的区间乘积(前缀和)(快速幂)

链接:https://ac.nowcoder.com/acm/contest/19483/A
来源:牛客网

题目描述

给定一个长度大小为N{N}N的正整数数组,查询M{M}M轮,每次问一个区间所有元素的连续乘积。
由于这个答案可能很大,你只用输出结果对109+7{10^9+7}109+7取余数后的结果即可。

输入描述:

第一行输入一个正整数N,M(1≤N,M≤105){N,M(1 \leq N,M \leq 10^5)}N,M(1N,M105)表示数组的长度和查询的次数。
接下来输入一行N{N}N个正整数ai(1≤ai≤109)a_i(1 \leq a_i \leq 10^9)ai(1ai109)表示数组的值。

输出描述:

请输出一个非负整数,表示区间所有数字的连续乘积对109+7{10^9+7}109+7取余数后的结果。
示例1

输入

5 3
5 2 3 10 6
1 5
2 3
2 5

输出

1800
6
360

备注:

注意要取模。

涉及挺多知识点的,记录一下
  

 

 代码附上:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define TL ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
 5 
 6 const ll mod = 1e9+7;
 7 int n,m,a[100009],l,r;
 8 ll s[100009];//用一个数组s存储前缀积
 9 ll binpow(ll a,ll b,ll mod) // 快速幂
10 {
11     ll res = 1;
12     while(b)
13     {
14         if(b&1) res = (res * a)%mod;
15         a = (a * a) % mod;
16         b >>= 1;
17     }
18     return res;
19 }
20 ll get_inv(ll x) //求取逆元
21 {
22     return binpow(x,mod-2,mod);
23 }
24 int main()
25 {
26     TL;
27     cin >> n >> m;
28     s[0] = 1;
29     for(int i = 1;i <= n;i++)
30     {
31         cin >> a[i];
32         s[i] = a[i] * s[i-1] % mod;
33     }
34     while(m--)
35     {
36         cin >> l >> r;
37         cout << s[r]*get_inv(s[l-1])%mod << endl;
38     }
39     return 0;
40 }

 

 

 


 

 


 

 


 

 


 

 


 

 



posted @ 2021-11-25 22:29  wbw1537  阅读(631)  评论(0)    收藏  举报