結果
| 問題 |
No.776 A Simple RMQ Problem
|
| コンテスト | |
| ユーザー |
rickytheta
|
| 提出日時 | 2018-12-12 13:01:52 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 434 ms / 3,000 ms |
| コード長 | 3,558 bytes |
| コンパイル時間 | 1,802 ms |
| コンパイル使用メモリ | 162,824 KB |
| 実行使用メモリ | 6,948 KB |
| 最終ジャッジ日時 | 2024-09-25 03:32:51 |
| 合計ジャッジ時間 | 13,704 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 26 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:125:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
125 | scanf("%d%d",&n,&q);
| ~~~~~^~~~~~~~~~~~~~
main.cpp:126:16: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
126 | REP(i,n)scanf("%d",a+i);
| ~~~~~^~~~~~~~~~
main.cpp:134:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
134 | scanf("%s",buf);
| ~~~~~^~~~~~~~~~
main.cpp:138:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
138 | scanf("%d%d",&i,&x); --i;
| ~~~~~^~~~~~~~~~~~~~
main.cpp:145:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
145 | scanf("%d%d%d%d",&l1,&l2,&r1,&r2); --l1; --l2; --r1; --r2;
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
ソースコード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define FORR(i,a,b) for(int i=(int)(b)-1;i>=(int)(a);i--)
#define CHMIN(a,b) (a)=min((a),(b))
#define CHMAX(a,b) (a)=max((a),(b))
const ll INF = 1ll<<60;
int n,q;
int a[125252];
ll sum[125252];
// sqrt decomposition
const int N = 100025; // max n
const int B = 252; // bucket size
const int C = (N+B-1)/B; // max bucket count
ll bucketMax[C], bucketMin[C], bucketVal[C];
ll lazyVal[C];
// O(n) calc for max_{l<r}(sum[r]-sum[l])
ll tmp[2*B+2*C+10];
ll calcMax[2*B+2*C+10];
ll calcVal(int n, ll *arr){
calcMax[n] = -INF;
FORR(i,0,n)calcMax[i] = max(calcMax[i+1], arr[i]);
ll ret = -INF;
ll mn = INF;
REP(i,n){
CHMIN(mn, arr[i]);
CHMAX(ret, calcMax[i+1] - mn);
}
return ret;
}
// bucket operation
void calcBucket(int id){
bucketMax[id] = -INF;
bucketMin[id] = INF;
lazyVal[id] = 0;
REP(i,B){
CHMAX(bucketMax[id], sum[id*B+i]);
CHMIN(bucketMin[id], sum[id*B+i]);
}
bucketVal[id] = calcVal(B, sum+id*B);
}
void addToBucket(int id, ll v){
bucketMax[id] += v;
bucketMin[id] += v;
lazyVal[id] += v;
}
void push(int id){
if(lazyVal[id]==0)return;
REP(i,B)sum[id*B+i] += lazyVal[id];
lazyVal[id] = 0;
}
void queryAdd(int l, int r, ll v){
int it = l;
// left bucket
push(it/B);
while(it<r && it%B>0)sum[it++] += v;
calcBucket(l/B);
// between bucket
while(it+B<=r){addToBucket(it/B, v); it+=B;}
// right bucket
push(it/B);
while(it<r)sum[it++] += v;
calcBucket(r/B);
}
ll queryMax(int l, int r){
ll ret = -INF;
int it = l;
// left bucket
push(it/B);
while(it<r && it%B>0)CHMAX(ret, sum[it++]);
// between bucket
while(it+B<=r){CHMAX(ret, bucketMax[it/B]); it+=B;}
// right bucket
push(it/B);
while(it<r)CHMAX(ret, sum[it++]);
return ret;
}
ll queryMin(int l, int r){
ll ret = INF;
int it = l;
// left bucket
push(it/B);
while(it<r && it%B>0)CHMIN(ret, sum[it++]);
// between bucket
while(it+B<=r){CHMIN(ret, bucketMin[it/B]); it+=B;}
// right bucket
push(it/B);
while(it<r)CHMIN(ret, sum[it++]);
return ret;
}
ll queryVal(int l, int r){
ll ret = -INF;
int it = l;
int m = 0;
// left bucket
push(it/B);
while(it<r && it%B>0)tmp[m++] = sum[it++];
// between bucket
while(it+B<=r){
CHMAX(ret, bucketVal[it/B]);
tmp[m++] = bucketMax[it/B];
tmp[m++] = bucketMin[it/B];
it += B;
}
// right bucket
push(it/B);
while(it<r)tmp[m++] = sum[it++];
CHMAX(ret, calcVal(m, tmp));
return ret;
}
ll f1(int l1, int l2, int r1, int r2){
return queryMax(r1+1, r2+2) - queryMin(l1, l2+1);
}
int main(){
// input
scanf("%d%d",&n,&q);
REP(i,n)scanf("%d",a+i);
// construct sqrt decomposition
sum[0] = 0;
REP(i,n)sum[i+1] = sum[i]+a[i];
REP(i,C)calcBucket(i);
// query
while(q--){
char buf[5];
scanf("%s",buf);
if(buf[0]=='s'){
// set i x
int i,x;
scanf("%d%d",&i,&x); --i;
ll diff = x - a[i];
a[i] = x;
queryAdd(i+1, n+1, diff);
}else{
// max l1 l2 r1 r2
int l1,l2,r1,r2;
scanf("%d%d%d%d",&l1,&l2,&r1,&r2); --l1; --l2; --r1; --r2;
r1 = max(r1, l1); l2 = min(l2, r2);
ll ans = -INF;
if(l2<=r1){
ans = f1(l1, l2, r1, r2);
}else{
ans = max(ans, f1(l1, l2, l2, r2));
ans = max(ans, f1(l1, r1, r1, r2));
ans = max(ans, queryVal(r1, l2+1));
}
printf("%lld\n",ans);
}
}
return 0;
}
rickytheta