牛客网子段乘积

子段乘积

添加链接描述
看了很多算法题解,对于小白的我来说,都看得不是很懂,所以往往看了别人的代码,还要自己整理一遍思路,现在把我写的一些注释分享给大家,大家一起学习!

#include
using namespace std;
typedef long long ll;
const int mod=998244353;
ll quick(ll a,ll b)//快速幂 快速幂的迭代写法
{
    ll ret=1;
    while(b)
    {			//因此当b 为奇数时 b & 1 返回为1,if条件成立,这样执行速度更快 
        if(b&1)//因此可以用if ((b & 1) == 0)代替if (b % 2 == 0)来判断a是不是偶数 
			ret=ret*a%mod;
        a=a*a%mod;
        b>>=1;//操作数每右移一位,相当于该数除以2。 右移 
    }
    return ret;
}
/*(1)初始令ans = 1,用来存放累积的结果。

(2)判断b的二进制末尾是否为1 ,(及判断 b&1 是否为 1),也可以理解为判断b 是否为奇数。如果是的话,令ans乘上a的值。

(3)令a平方,并使b右移一位,(也可以理解为,b/2)

(4)只要b 大于0,就返回(2)。
*/

ll inv(ll a){
	return quick(a,mod-2);//a的mod-2次方 
}

typedef vector<int> vi;
int main()
{
    ll ans=0;
    int n,k;
    cin>>n>>k;
    int zero=0;
    ll cur=1;
    vi a(n);//定义一个vi容器,大小为n,命名为a 
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        if(!a[i]) 
			zero++;//零加一 
        else 
			cur=cur*a[i]%mod;//非零相乘取模 
        if(i>=k)//i大于连续子段长度 
        {
            if(!a[i-k]) 
				zero--;//零减一 
            else //inv(a[i-k])表示a[i-k]的mod-2次方 
				cur=cur*inv(a[i-k])%mod;//如果初始值a大于mod,那么需要在进入函数前就让a对mod取模,
        }
        if(i>=k-1&&!zero) //zero==0,满足条件       
			ans=max(ans,cur);
    }
    cout<<ans<<'\n';
    return 0; 
}

希望对大家有帮助,嘻嘻!

你可能感兴趣的:(算法题)