結果
問題 | No.776 A Simple RMQ Problem |
ユーザー |
![]() |
提出日時 | 2018-12-11 23:30:59 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 384 ms / 3,000 ms |
コード長 | 3,463 bytes |
コンパイル時間 | 1,290 ms |
コンパイル使用メモリ | 164,100 KB |
実行使用メモリ | 13,688 KB |
最終ジャッジ日時 | 2024-09-24 08:49:21 |
合計ジャッジ時間 | 10,837 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 26 |
コンパイルメッセージ
main.cpp: In function ‘int main()’: main.cpp:85:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 85 | scanf("%d%d",&n,&q); | ~~~~~^~~~~~~~~~~~~~ main.cpp:86:16: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 86 | REP(i,n)scanf("%lld",a+i); | ~~~~~^~~~~~~~~~~~ main.cpp:107:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 107 | scanf("%s",buf); | ~~~~~^~~~~~~~~~ main.cpp:111:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 111 | scanf("%d%d",&i,&x); --i; | ~~~~~^~~~~~~~~~~~~~ main.cpp:118:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result] 118 | 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--)const ll INF = 1ll<<60;int n,q;ll a[125252];ll sum[125252];// segment treeconst int N = 1<<17;ll datMin[2*N], datMax[2*N]; // range min/maxll datVal[2*N]; // (max. dat[j]-dat[i] s.t. l<=i<j<=r)bool lazyFlag[2*N];ll lazyVal[2*N];void push(int k){if(!lazyFlag[k])return;datMin[k] += lazyVal[k];datMax[k] += lazyVal[k];if(k<N-1){lazyFlag[2*k+1] = lazyFlag[2*k+2] = true;lazyVal[2*k+1] += lazyVal[k];lazyVal[2*k+2] += lazyVal[k];}lazyFlag[k] = false;lazyVal[k] = 0;}void queryAdd(int l, int r, ll v, int a, int b, int k){push(k);if(r<=a || b<=l)return;if(l<=a && b<=r){lazyFlag[k] = true;lazyVal[k] += v;push(k);return;}int m = (a+b)/2;queryAdd(l,r,v,a,m,2*k+1);queryAdd(l,r,v,m,b,2*k+2);datMin[k] = min(datMin[2*k+1], datMin[2*k+2]);datMax[k] = max(datMax[2*k+1], datMax[2*k+2]);datVal[k] = max(datVal[2*k+1], datVal[2*k+2]);datVal[k] = max(datVal[k], datMax[2*k+2] - datMin[2*k+1]);}void queryAdd(int l, int r, ll v){queryAdd(l,r,v,0,N,0);}// <<min, max>, val>pair<pair<ll,ll>,ll> queryGet(int l, int r, int a, int b, int k){push(k);if(r<=a || b<=l)return make_pair(make_pair(INF, -INF), -INF);if(l<=a && b<=r)return make_pair(make_pair(datMin[k], datMax[k]), datVal[k]);int m = (a+b)/2;pair<pair<ll,ll>,ll> lft, rgt;lft = queryGet(l,r,a,m,2*k+1);rgt = queryGet(l,r,m,b,2*k+2);ll mn = min(lft.first.first, rgt.first.first);ll mx = max(lft.first.second,rgt.first.second);ll vl = max(lft.second, rgt.second);vl = max(vl, rgt.first.second - lft.first.first);return make_pair(make_pair(mn,mx),vl);}ll queryMin(int l, int r){return queryGet(l,r,0,N,0).first.first;}ll queryMax(int l, int r){return queryGet(l,r,0,N,0).first.second;}ll queryVal(int l, int r){return queryGet(l,r,0,N,0).second;}ll f1(int l1, int l2, int r1, int r2){assert(l2<=r1);return queryMax(r1+1, r2+2) - queryMin(l1, l2+1);}int main(){// inputscanf("%d%d",&n,&q);REP(i,n)scanf("%lld",a+i);// construct segment treeREP(i,n)sum[i+1] = sum[i]+a[i];REP(i,n+1){datMin[i+N-1] = datMax[i+N-1] = sum[i];datVal[i+N-1] = -INF;}FOR(i,n+1,N){datMin[i+N-1] = INF;datMax[i+N-1] = -INF;datVal[i+N-1] = -INF;}FORR(i,0,N-1){datMin[i] = min(datMin[2*i+1], datMin[2*i+2]);datMax[i] = max(datMax[2*i+1], datMax[2*i+2]);datVal[i] = max(datVal[2*i+1], datVal[2*i+2]);datVal[i] = max(datVal[i], datMax[2*i+2] - datMin[2*i+1]);}// querywhile(q--){char buf[5];scanf("%s",buf);if(buf[0]=='s'){// set i xint 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 r2int 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);assert(l1<=r1 && 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;}