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; 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"; } } }
|