Submission #62114
ソースコード
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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #include<bits/stdc++.h> using namespace std; /*SegTree<x>(n,fx,ex): モノイド(集合X,二項演算fx,単位元ex)についてサイズnで構築 set(int i,X x),build(): i番目の要素をxにセット。まとめてセグ木を構築する0(n) update(i,x): i番目の要素をxに更新。O(log(n)) query(a,b): [a,b) 全てにfxを作用させた値を取得。O(log(n)) operator[k] := k番目の要素を返す。 find_rightest : [a,b) で x以下の要素を持つ最右位置はどこか find_leftest : [a,b) で x以下の要素を持つ最左位置はどこか */ template < typename X> struct SegTree{ using FX=function<X(X,X)>; //X●X -> X となる関数の型 int n; FX fx; const X ex; vector<X> dat; SegTree( int size,FX fx_,X ex_) : n(),fx(fx_),ex(ex_),dat(size*4,ex_){ int x=1; while (size>x){ x*=2; } n=x; return ; } void set( int i,X x){ dat[i+n-1]=x;} void build(){ for ( int k=n-2;k>=0;k--) dat[k]=fx(dat[2*k+1],dat[2*k+2]); return ; } void update( int i,X x){ i+=n-1; dat[i]=x; while (i>0){ i=(i-1)/2; dat[i]=fx(dat[i*2+1],dat[i*2+2]); } return ; } X query( int a, int b){ return (query_sub(a,b,0,0,n));} X query_sub( int a, int b, int k, int l, int r){ if (r<=a || b<=l){ return ex; } else if (a<=l && r<=b){ return dat[k]; } else { X vl=query_sub(a,b,k*2+1,l,(l+r)/2); X vr=query_sub(a,b,k*2+2,(l+r)/2,r); return fx(vl,vr); } } X operator[]( const int &k) const { return dat[k+n-1]; } X find_rightest( int a, int b, X x) { return find_rightest_sub(a, b, x, 0, 0, n); } X find_leftest( int a, int b, X x) { return find_leftest_sub(a, b, x, 0, 0, n); } X find_rightest_sub( int a, int b, X x, int k, int l, int r) { if (dat[k] > x || r <= a || b <= l) { // 自分の値がxより大きい or [a,b)が[l,r)の範囲外 return a - 1; } else if (k >= n - 1) { // 自分が葉ならその位置をreturn return (k - (n - 1)); } else { int vr = find_rightest_sub(a, b, x, 2 * k + 2, (l + r) / 2, r); if (vr != a - 1) { // 右の部分木を見て a-1 以外ならreturn return vr; } else { // 左の部分木を見て値をreturn return find_rightest_sub(a, b, x, 2 * k + 1, l, (l + r) / 2); } } } X find_leftest_sub( int a, int b, X x, int k, int l, int r) { if (dat[k] > x || r <= a || b <= l) { // 自分の値がxより大きい or [a,b)が[l,r)の範囲外 return b; } else if (k >= n - 1) { // 自分が葉ならその位置をreturn return (k - (n - 1)); } else { int vl = find_leftest_sub(a, b, x, 2 * k + 1, l, (l + r) / 2); if (vl != b) { // 左の部分木を見て b 以外ならreturn return vl; } else { // 右の部分木を見て値をreturn return find_leftest_sub(a, b, x, 2 * k + 2, (l + r) / 2, r); } } } }; int main(){ int n,m; cin>>n>>m; auto fx=[]( int x1, int x2) -> int { return min(x1,x2);}; int ex=numeric_limits< int >::max(); SegTree< int > minseg(n,fx,ex); auto fx2=[]( int x1, int x2) -> int { return max(x1,x2);}; int ex2=-ex; SegTree< int > maxseg(n,fx2,ex2); auto fx3=[]( int x1, int x2) -> int { return (x1+x2);}; int ex3=0; SegTree< int > sumseg(n,fx3,ex3); string s; int a,b; for ( int i=0;i<n;i++){ minseg.update(i,0); maxseg.update(i,0); sumseg.update(i,0); } for ( int i=0;i<m;i++){ cin>>s>>a>>b; if (s== "update" ){ minseg.update(a,b); maxseg.update(a,b); sumseg.update(a,b); } else if (s== "add" ){ minseg.update(a,minseg[a]+b); maxseg.update(a,maxseg[a]+b); sumseg.update(a,sumseg[a]+b); } else if (s== "getMin" ){ cout<<minseg.query(a,b)<< '\n' ; } else if (s== "getMax" ){ cout<<maxseg.query(a,b)<< '\n' ; } else { cout<<sumseg.query(a,b)<< '\n' ; } } return (0); } |
ステータス
項目 | データ |
---|---|
問題 | 1072 - セグメントツリー技術基礎 |
ユーザー名 | ei1918 |
投稿日時 | 2020-08-13 15:41:26 |
言語 | C++14 |
状態 | Accepted |
得点 | 1 |
ソースコード長 | 4238 Byte |
最大実行時間 | 209 ms |
最大メモリ使用量 | 10752 KB |
セット
セット | 得点 | Cases | |
---|---|---|---|
1 | ALL | 1 / 1 | * |
テストケース
ファイル名 | 状態 | 実行時間 | メモリ使用量 | # |
---|---|---|---|---|
in01 | AC | 28 ms | 604 KB |
1
|
in02 | AC | 130 ms | 960 KB |
1
|
in03 | AC | 112 ms | 5296 KB |
1
|
in04 | AC | 156 ms | 5228 KB |
1
|
in05 | AC | 63 ms | 5644 KB |
1
|
in06 | AC | 87 ms | 3472 KB |
1
|
in07 | AC | 114 ms | 3196 KB |
1
|
in08 | AC | 176 ms | 2948 KB |
1
|
in09 | AC | 167 ms | 5452 KB |
1
|
in10 | AC | 182 ms | 3840 KB |
1
|
in11 | AC | 43 ms | 3360 KB |
1
|
in12 | AC | 72 ms | 2564 KB |
1
|
in13 | AC | 160 ms | 7248 KB |
1
|
in14 | AC | 209 ms | 4040 KB |
1
|
in15 | AC | 121 ms | 6872 KB |
1
|
in16 | AC | 157 ms | 3888 KB |
1
|
in17 | AC | 148 ms | 6764 KB |
1
|
in18 | AC | 78 ms | 8012 KB |
1
|
in19 | AC | 140 ms | 7452 KB |
1
|
in20 | AC | 87 ms | 7396 KB |
1
|
in21 | AC | 106 ms | 6548 KB |
1
|
in22 | AC | 190 ms | 6932 KB |
1
|
in23 | AC | 138 ms | 8792 KB |
1
|
in24 | AC | 142 ms | 7612 KB |
1
|
in25 | AC | 164 ms | 6032 KB |
1
|
in26 | AC | 191 ms | 9936 KB |
1
|
in27 | AC | 162 ms | 9952 KB |
1
|
in28 | AC | 194 ms | 7580 KB |
1
|
in29 | AC | 71 ms | 9520 KB |
1
|
in30 | AC | 170 ms | 10752 KB |
1
|
in31 | AC | 104 ms | 8420 KB |
1
|
in32 | AC | 172 ms | 8436 KB |
1
|