アイデア:ツリーライン、更新間隔、間隔を検索します
1の#include <iostreamの> 2の#include <ベクトル> 3の#include < ストリング > 4の#include <cmath> 5の#include < 設定 > 6の#include <アルゴリズム> 7の#include <cstdioを> 8の#include <地図> 9# <CStringの>含む 10の#include <リスト> 11 12 の#define MAXSIZE 100010 13 14 使って 名前空間STDを、 15 16 長い 長い木[ 4 * MAXSIZE]。 長い LZ [ 4 * MAXSIZE]。 18 int型N、Q; 19 20 ボイドのinit() 21 { 22 のmemset(木、0、はsizeof (木))。 23 のmemset(LZ、0、はsizeof (LZ))。 24 } 25 26 ボイドビルド(int型ノード、int型の L、INT R) 27 { 28 であれば(L == R) 29 { 30 のscanf("%のLLD 」、&ツリー[ノード]); 31 リターン; 32 } 33 34 INT半ば=(L + R)/ 2 ; 35 ビルド(ノード* 2 、L、MID); 36 ビルド(ノード* 2 + 1、中間+ 1 、R); 37 38 ツリー[ノード] =ツリー[ノード* 2 ] +ツリー[ノード* 2 + 1 ]; 39 } 40 41 空隙 push_down(int型ノード、int型の L、INTR) 42 { 43 であれば(LZ [ノード]) 44 { 45 INT半ば=(L + R)/ 2 。 46の LZ [ノード* 2 ] + = LZ [ノード]。 47の LZ [ノード* 2 + 1 ] + = LZ [ノード]。 48 ツリー[ノード* 2 ] + =(MID-L + 1)* LZ [ノード]。 49 ツリー[ノード* 2 + 1 ] + =(R-MID)* LZ [ノード]。 50の LZ [ノード] = 0 ; 51 } 52 } 53 54 空隙 update_range(int型ノード、int型の L、int型の R、int型の L、int型の R、int型のADD) 55 { 56 であれば(L <= L && R> = R) 57 { 58 LZ [ノード] + = 追加; 59 ツリー[ノード] + =(R-L + 1)* 加えます。 60 リターン; 61 } 62 push_down(ノード、L、R)。 63 INT半ば=(L + R)/ 2 。 64 であれば(MID> = L) 65 (ノード* update_range 2 、L、R、L、中間、追加)。 66 であれば(MID < 商標) 67 update_range(ノード* 2 + 1、L、R、中間+ 1 、R、追加)。 68 ツリー[ノード]はツリー[ノード* = 2 ] +ツリー[ノード* 2 + 1 ]。 69 } 70 71 長い 長い query_range(int型ノード、int型の L、int型の R、int型の L、INT R) 72 { 73 であれば(L <= L && R> = R) 74 { 75 リターン・ツリー[ノード]。 76 } 77 push_down(ノード、L、R)。 78 INT半ば=(L + R)/ 2 。 79 長い 長い和= 0 。 80 であれば(MID> = L) 81 合計+ = query_range(ノード* 2 、L、R、L、MID)。 82 であれば(MID < 商標) 83 合計+ = query_range(ノード* 2 + 1、L、R、ミッド+1 、R)。 84 85 リターン合計。 86 } 87 88 89 90 のint main()の 91 { 92 のscanf(" %d個の%のD "、&N、&Q)。 93 のinit(); 94 ビルド(1、1 、N)。 95 一方(Q-- ) 96 { 97 チャーCH。 98 のscanf(" %のC "、&CH); 99 もし(CH ==' Q ' ) 100 { 101 int型A、B。 102 のscanf(" %D%dの"、&、&B)。 103 のprintf(" %LLDする\ n "、query_range(1、A、B、1 、N))。 104 } 105 そう なら(CH == ' C ' ) 106 { 107 int型A、B、C。 108 のscanf(" %D%D%D "、&A、&B、&C); 109 update_range(1、A、B、1 、N、C)。 110 } 111 } 112 113 114 リターン 0 。 115 }