https://ac.nowcoder.com/acm/contest/3005/C
题意:求长度为k的连续子段乘积。
解法1逆元:前缀乘积(不含0),记录前缀0的个数,并求不含0的长度为k的连续子段乘积中取最大的。
注意0没有逆元,所以在考虑递推方法时0要特殊处理。
#include <bits/stdc++.h>
#define ME(x , y) memset(x , y , sizeof(x))
#define SC scanf
#define rep(i ,j , n) for(int i = j ; i < n ; i ++)
#define red(i , n , j) for(int i = n-1 ; i >= j ; i--)
#define INF 0x3f3f3f3f
#define mod 998244353
#define PI acos(-1)
#define lson k<<1,l,mid
#define rson k<<1|1,mid+1,r
using namespace std;
typedef long long ll ;
const int MX = 1e5+9;
ll pre[200009];
ll a[200009];
int cnt0[200009];//前缀0的个数
ll quickpow(ll a , ll b){
ll ans = 1 ;
while(b){
if(b&1) ans = ans%mod * a % mod;
b >>= 1 ;
a = a%mod * a %mod;
}
return ans;
}
int main() {
int n , k ;
cin >> n >> k;
pre[0] = 1 ;
rep(i , 1 , n+1){
scanf("%lld" , &a[i]);
}
rep(i , 1 , n+1){
if(a[i] == 0){
pre[i] = pre[i-1];
cnt0[i] = cnt0[i-1]+1;
}else{
pre[i] = (pre[i-1]*a[i])%mod;
cnt0[i] = cnt0[i-1];
}
}
ll ans = 0;
rep(i , k , n+1){
int j = i-k+1;
if(cnt0[i] == cnt0[j-1]){//长度k连续子段不含0
ll temp = pre[i]*quickpow(pre[j-1] , mod-2)%mod;
ans = max(ans , temp);
}
}
cout << ans << endl;
return 0 ;
}
解法2:线段树O(nlogn)求每一段连续k乘积
#include <bits/stdc++.h>
#define ME(x , y) memset(x , y , sizeof(x))
#define SC scanf
#define rep(i ,j , n) for(int i = j ; i < n ; i ++)
#define red(i , n , j) for(int i = n-1 ; i >= j ; i--)
#define INF 0x3f3f3f3f
#define mod 998244353
#define PI acos(-1)
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
using namespace std;
typedef long long ll ;
const int maxn = 2e5+9;
ll val[maxn<<2];
void build(int l , int r , int root){
if(l == r){
scanf("%lld" , &val[root]);
return ;
}
int mid = (l + r)>>1;
build(lson);
build(rson);
val[root] = val[root<<1]%mod * val[root<<1|1]%mod ;
}
ll query(int l , int r , int root , int L , int R){
if(l >= L && r <= R){
return val[root]%mod;
}
ll sum = 1 ;
int mid = (l+r) >> 1;
if(L <= mid)
sum = sum%mod * query(lson , L , R)%mod;
if(mid < R)
sum = sum%mod * query(rson , L , R)%mod;
return sum%mod ;
}
int main()
{
int n , k ;
cin >> n >> k;
build(1 , n , 1);
ll ans = 0 ;
rep(i , k , n+1){
ans = max(ans , query(1 , n , 1 , i-k+1 , i));
}
cout << ans << endl;
return 0;
}