字段乘積

傳送門
兩種方法:

1:逆元

必須用逆元解決除回去不是原數字的尷尬局面。
eg:
如果0.5/3=x那麼x*3還等於0.5嗎?
顯然不能,那麼逆元就好了

代碼:

#include<iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <functional>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <algorithm>
#define ll long long
#define mes(x,y) memset(x,y,sizeof(x))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll GCD(ll a, ll b) {//最大公約數
	return b == 0 ? a : GCD(b, a % b);
}
ll Power(ll a, ll b, ll p) { //計算(a^b)%p;
	ll ans = 1;
	while (b) {
		if (b & 1) //等價於b%2,判斷b的奇偶性
			ans = ans * a % p; //如果爲奇數,證明該位爲1,需要乘上a
		a = a * a % p; //計算a^(2^i)
		b >>= 1; //等價於b/=2;
	}
	return ans;
}
bool isprime(int num)
{
	if (num == 2 || num == 3)
		return true;
	if (num % 6 != 1 && num % 6 != 5)
		return false;
	int t = sqrt((double)num);
	for (int i = 5; i <= t; i += 6)
	{
		if (num % i == 0 || num % (i + 2) == 0)
			return false;
	}
	return true;
}



const ll mod = 998244353;
const ll maxn = 1e9 + 10;
ll a[2000300];
int main() {
	ll n, m, i, j, k;
	string s;
	while (cin >> n >> m) {
		ll sum = 1;
		ll maxv = 0;
		mes(a, 0);
		for (i = 0, j = 0; i < n; i++) {
			cin >> a[i];
			if (a[i] == 0)j = 0, sum = 1;
			else {
				sum = sum * a[i] % mod;
				j++;
				if (j >= m) {
					//cout << i << ":" <<(ll)sum<<" "<< ((ll)sum % mod) << endl << endl;
					maxv = max(maxv, sum);
					sum = sum * Power(a[i - m + 1], mod - 2, mod) % mod;
				}
			}
		}
		cout << maxv << endl;
	}
}

2:線段樹:

這個採用了取巧的方法,不用除,只需找到那一段的乘積即可。

代碼:

#include<iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <functional>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <algorithm>
#define ll long long
#define mes(x,y) memset(x,y,sizeof(x))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
ll GCD(ll a, ll b) {//最大公約數
    return b == 0 ? a : GCD(b, a % b);
}
ll Power(ll a, ll b, ll p) { //計算(a^b)%p;
    ll ans = 1;
    while (b) {
        if (b & 1) //等價於b%2,判斷b的奇偶性
            ans = ans * a % p; //如果爲奇數,證明該位爲1,需要乘上a
        a = a * a % p; //計算a^(2^i)
        b >>= 1; //等價於b/=2;
    }
    return ans;
}
bool isprime(int num)
{
    if (num == 2 || num == 3)
        return true;
    if (num % 6 != 1 && num % 6 != 5)
        return false;
    int t = sqrt((double)num);
    for (int i = 5; i <= t; i += 6)
    {
        if (num % i == 0 || num % (i + 2) == 0)
            return false;
    }
    return true;
}
 
const ll MOD = 998244353;
 
struct node
{
    int l, r;
    ll v;
}node[1500005];
void PushUp(int numb)       //  向父節點更新數據;
{
    node[numb].v = (node[numb << 1].v % MOD) * (node[numb << 1 | 1].v % MOD) % MOD;
}
void build(int l, int r, int numb)     // 建樹;
{
    node[numb].l = l;
    node[numb].r = r;
    node[numb].v = 0;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(l, mid, numb << 1);
    build(mid + 1, r, numb << 1 | 1);
}
void Insert(int numb, int t, ll v) {
    int l = node[numb].l, r = node[numb].r;
    if (l == r && l == t) {
        node[numb].v = v;
        return;
    }
    int mid = (l + r) >> 1;
    if (t > mid) Insert(numb << 1 | 1, t, v);
    else if (t <= mid) Insert(numb << 1, t, v);
    PushUp(numb);
}
ll query(int l, int r, int numb) {
    if (node[numb].l == l && node[numb].r == r) {
        return node[numb].v;
    }
    int mid = (node[numb].l + node[numb].r) >> 1;
    if (l > mid) return query(l, r, numb << 1 | 1);
    else if (r <= mid) return query(l, r, numb << 1);
    else {
        return (query(l, mid, numb << 1) * query(mid + 1, r, numb << 1 | 1)) % MOD;
    }
}
int main() {
    ll k, n, q, a, b;
    while (cin >> n >> k) {
        build(1, n, 1);
        for (int i = 1; i <= n; i++) {
            cin >> a;
            Insert(1, i, a);
        }
        ll ans = 0;
        for (int i = 1; i <= n - k + 1; i++) {
            ll t = query(i, i + k - 1, 1);
            ans = max(ans, t);
        }
        cout << ans << endl;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章