これは、多くの柯Duoliツリーああのようなものです〜
アイデアは非常に巧妙です。
コード:
#include <cstdioを> する#include <セット> の#include <マップ> の#include <ベクトル> の#include <アルゴリズム> の#include <CStringの> する#include <ストリング> の#define N 500009 の#defineっ長い長 の#define setIO(S) freopenは(S ".IN"、 "R"、STDIN) 名前空間stdを使用。 名前空間BIT { LL C [N]。 INT lowbit(INT T){戻りT&( - T)。} LLクエリ(INT X) { LL再= 0。 (; X> 0; X- = lowbit(x))を再+ = C [X]のために、 再を返します。 } ボイド更新(INTのX、LL V){ため(; X <Nであり、X + = lowbit(x))をC [X] + = V。} }。 構造体ノード { INT L、R、V、D。 ノード(INT L = 0、INT R = 0、INT V = 0、int型D = 0)、L(リットル)、R(R)、V(V)、D(D){} ブール演算子<(ノードB )CONST {戻りL <BL。} } [N]、CN [N]。 セット<ノード> SE。 <ノード> ::イテレータトンに設定。 {int型のL、R、IDを尋ねる構造体。}として[N]。 ブールCMP(B尋ねる、頼む){戻りAR <BR。} ボイドスプリット(ノードA、INT POS) { IF(アル== AR || POS <=ら|| POS> AR)のリターン; ノードP = A。 ()se.erase。 PL = POS、AR = POS-1。 se.insert()。 se.insert(P)。 } ボイド挿入(ノードA) { ため(INT I 1 =; I <= TOT; ++ I)se.erase(CN [I])。 INT L =ら、R = AR、V = AV、D =広告、TOT = 0。 セット<ノード> ::イテレータITL、ITR、それは。 ITL = se.lower_bound(ノード(L + 1,0,0,0))。 もし(ITL = se.begin()!)--itl、スプリット(* ITL、L); ITR = se.lower_bound(ノード(R + 1,0,0,0))。 もし(ITR = se.begin()!)--itr、スプリット(* ITR、R + 1); ITL = se.lower_bound(ノード(L、0,0,0))。 ITR = se.lower_bound(ノード(R + 1,0,0,0))。 以下のため(それがITLを=;それ= ITR;!それ++) { BIT ::更新((*それ).D、 - (LL)((*それ).R - (* IT)・L + 1)*(*それ)・V); CN [++ TOT] = *それ。 } BIT ::更新(広告、(LL)(AR-a.l + 1)* AV)。 se.insert()。 } int型のmain() { // setIO( "入力")。 私は、jはint型。 scanf関数( "%D%D%D"、&N、&M&Q)。 ための式(I = 1; iが<= N; ++ I)のscanf( "%D%D%D"、および[I] .L、&[I] .R&[I] .V)、[ i]は.D = I; ため(I 1 =、iが<= Q; ++ I)のscanf( "%D%D"、および[I] .L、&として[I] .Rなど)、などの[I] .ID = I。 ソート(+ 1 + Q、CMPのような、1 +など); ため(J = I = 1; I <= Q; ++ I) { ため(; J <= N && [J] .D <=として[I] .R; ++ j)の挿入([J]) ; = BIT ::クエリ([I] .Rとして)ビット[[I] .IDとして]回答::([I] .L-1など)のクエリ。 } のためには、(i 1 =; I <= Q; ++ I)のprintf( "%のLLD \ n"は、回答[I])。 0を返します。 }