E

考虑 $S_i$ 时间进去的时候更新一个地方的 $X$ 值。

然后 $T_i$ 时间用 $X$ 值去更新标记。

准确说,是一个类似 lazytag 的东西。

F

其实可以把唯一分解之后的指数相加。

然后就是简单的博弈题了。

G

考虑 $B \ge 2$ 的不会超过 $\log$ 个,所以其实是个诈骗了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
void solve() {
int n;
cin>>n;
vi a(n),b(n);
rep(n)cin>>a[i];
rep(n)cin>>b[i];
int q;cin>>q;

vl aa(n*2);
rep(n)aa[i+n]=a[i];
for(int i=n-1;i>=0;i--)aa[i]=aa[i*2]+aa[i*2+1];
auto upd=[&](int i,int x){
i+=n;
aa[i]=x;
while(i>>=1)aa[i]=aa[i*2]+aa[i*2+1];
};
auto query=[&](int l,int r){
ll res=0;
l+=n;r+=n;
while(l<r){
if(l&1){
res+=aa[l++];
}
if(r&1){
res+=aa[--r];
}
l>>=1;r>>=1;
}
return res;
};
set<int>bb;
rep(i,n)if(b[i]>1)bb.emplace(i);
rep(t,q){
int op;
cin>>op;
if(op==1){
int i,x;cin>>i>>x;
--i;a[i]=x;
upd(i,a[i]);
}else if(op==2){
int i,x;cin>>i>>x;
--i;
if(b[i]>1)bb.erase(i);
b[i]=x;
if(b[i]>1)bb.emplace(i);
}else{
int l,r;cin>>l>>r;
--l;
vi cand;
auto it=bb.lower_bound(l);
while(true){
if(it==bb.end())break;
if(*it>=r)break;
cand.pb(*it);
it++;
}
int lst=l;
ll ans=0;
// debug(cand,a,b);
for(int i:cand){
ll aa=query(lst,i);
ll cur=max(ans+aa+a[i],(ans+aa)*b[i]);
cmax(ans,cur);
lst=i+1;
}
ll aa=query(lst,r);
ans+=aa;
cout<<ans<<"\n";
}
}
}