結果
| 問題 |
No.776 A Simple RMQ Problem
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-06-20 13:03:45 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,736 bytes |
| コンパイル時間 | 2,363 ms |
| コンパイル使用メモリ | 220,732 KB |
| 最終ジャッジ日時 | 2025-01-22 10:28:09 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 20 WA * 6 |
ソースコード
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
return (ull)rng() % B;
}
// 最大部分列をセグ木で求める
struct monoid{
ll ans; // その区間における最大部分列
ll L,R; // 左(右)側累積和最大値
ll sum; // 区間の総和
monoid(){
ans=-1e18;
L=R=0;
sum=0;
}
monoid(ll x){
ans=x;
L=R=max(x,0LL);
sum=x;
}
};
monoid f(monoid A,monoid B){
monoid res;
res.L=max(A.L,A.sum+B.L);
res.R=max(B.R,B.sum+A.R);
res.sum=A.sum+B.sum;
res.ans=max(A.ans,B.ans);
res.ans=max(res.ans,A.R+B.L);
return res;
}
struct SegmentTree{
int sz;
vector<monoid> seg;
SegmentTree(int n){
sz=1;
while(sz<n)sz<<=1;
seg.resize(2*sz);
}
void set(int i,ll x){
seg[i+sz]=monoid(x);
}
void init(){
for(int i=sz-1;i>0;i--){
seg[i]=f(seg[2*i],seg[2*i+1]);
}
}
void update(int k,ll x){
k+=sz;
seg[k]=monoid(x);
while(k>>=1){
seg[k]=f(seg[2*k],seg[2*k+1]);
}
}
monoid query(int l,int r){
monoid L,R;
if(l>=r)return L;
for(l+=sz,r+=sz;l<r;l>>=1,r>>=1){
if(l&1) L=f(L,seg[l++]);
if(r&1) R=f(seg[--r],R);
}
return f(L,R);
}
ll query(int l1,int r1,int l2,int r2){
// [l1,r1), [l2,r2)
if(r1<=l2){
return query(l1,r1-1).R+query(r1-1,l2+1).sum+query(l2+1,r2).L;
}
else{ // l2<r1
ll res=-1e18;
// l2を含む場合
res=max(res,query(l1,l2).R+query(l2+1,r2).L+seg[l2+sz].sum);
// r1-1を含む場合
res=max(res,query(l1,r1-1).R+query(r1,r2).L+seg[r1-1+sz].sum);
// [l2+1,r1-1)の場合
if(l2+1<r1-1)res=max(res,query(l2+1,r1-1).ans);
return res;
}
}
};
int main(){
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n,q; cin >> n >> q;
SegmentTree seg(n);
for(int i=0;i<n;i++){
ll a; cin >> a;
seg.set(i,a);
}
seg.init();
while(q--){
string op; cin >> op;
if(op=="set"){
int i,x; cin >> i >> x;
seg.update(i-1,x);
}
else{
// 問題文と変数の対応が変わってます
int l1,l2,r1,r2; cin >> l1 >> r1 >> l2 >> r2;
l1--; l2--;
l2=max(l2,l1);
r1=min(r1,r2);
printf("%lld\n",seg.query(l1,r1,l2,r2));
}
}
}