给定长为 (n) 的序列 (x_0,x_1,cdots,x_{n-1};y_0,y_1,cdots,y_{n-1})。
Catcats 在养猫猫,第 (0) 年有 (1) 只猫猫。若第 (i) 年初始有 (k) 只猫猫,则第 (i) 年末尾时有 (x_ik) 只猫猫。
第 (i) 年末尾时可以卖任意多只猫猫,每只猫猫 (y_i) 元。
支持 (m) 次单点修改并求最大收益(mod(10^9+7))。
(nle 5cdot 10^5,mle 10^5)。
答案即为 (max{y_iprod_{j=1}^ix_jmid iin[1,n]})。直接用线段树维护即可。
坑:zkw 线段树建树时要跑满。
#include"horses.h"
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int M = 1<<19, N = M<<1, mod = 1e9 + 7;
int s[N], v[N], X[N], Y[N]; double S[N], V[N];
void upd(int p, int x, int y){
p += M; s[p] = x; v[p] = (LL)x * y % mod;
S[p] = log(x); V[p] = S[p] + log(y); p >>= 1;
while(p){
int ls = p<<1, rs = ls|1;
s[p] = (LL)s[ls] * s[rs] % mod;
S[p] = S[ls] + S[rs];
if(V[ls] > S[ls] + V[rs]){
V[p] = V[ls]; v[p] = v[ls];
} else {
V[p] = S[ls] + V[rs];
v[p] = (LL)s[ls] * v[rs] % mod;
} p >>= 1;
}
} int init(int n, int x[], int y[]){
upd(0, 1, 0);
for(int i = 1;i <= n;++ i) upd(i, X[i] = x[i-1], Y[i] = y[i-1]);
for(int i = n+1;i < M;++ i) upd(i, 0, 0);
return v[1];
} int updateX(int pos, int val){
++ pos; upd(pos, X[pos] = val, Y[pos]); return v[1];
} int updateY(int pos, int val){
++ pos; upd(pos, X[pos], Y[pos] = val); return v[1];
}