効果の件名:
ソリューション:
カードのポイント:
C ++コード:
#include <cstdioを> する#include <CStringの> する#include <アルゴリズム> の#include <iostreamの> CONST INT MAXN = 2E5 + 10。 N INT、POS [MAXN]。 チャーS [MAXN]。 INT NXT [MAXN] [26]、[MAXN]、R [MAXN]、MNR [MAXN]失敗。 INT IDX = 1、LST = 1; 名前空間SGT { CONST int型N = MAXN << 2。 長い長いV [N]、TG [N]、TG2 [N]。 インラインボイドaddtg(INT RT、INT LEN、長い長いV){ V [RT] + = Vの*のLEN。 TG [RT] + = V。 } インラインボイドaddtg2(int型RT、INT LEN、長い長L、長い長いV){ V [RT] + =のL * LEN +(LEN * V)*(LEN + 1)/ 2。 TG [RT] + = L。 TG2 [RT] + = V。 } インラインボイドプッシュダウン(int型RT、INT LEN){ IF(TG [RT] || TG2 [RT]){ const int型L = RT << 1、R = RT << 1 | 1; addtg(L、LEN + 1 >> 1、TG [RT])。 addtg(R、LEN >> 1、TG [RT])。 addtg2(Lにおいてlen + 1 >> 1、TG2 [RT] *(LEN >> 1)、TG2 [RT])。 addtg2(R、LEN >> 1、0、TG2 [RT])。 TG [RT] = TG2 [RT] = 0; } } インラインボイド更新(INT RT){ V [RT] = V [RT << 1] + V [RT << 1 | 1]。 } ボイド(INT RT、INT L、のint R、int型のL、INT R、長い長いV){修正する (L <= 1 && R> = R){もし 、 - addtg(L + 1、V RT、r)を 返します。 } プッシュダウン(RT、R - L + 1)。 CONST INT半ば= L + R >> 1。 もし(L <= MID)(RT <変更 IF(R> MID)変更(RT << 1 | 1、中間+ 1、R、L、R、V)。 アップデート(RT)。 } ボイドmodify2(INT RT、INT L、のint R、int型のL、INT R、長い長いV){ (L <= 1 && R> = R)であれば{ CONST INT LL = R - R、LEN = R - L + 1; addtg2(RT、R - L + 1、LLの*のV、V)。// LL + V、LL + 2V、LL + 3V ... 返します。 } プッシュダウン(RT、R - L + 1)。 CONST INT半ば= L + R >> 1。 IF(L <= MID)modify2(RT << 1、L、中間、L、R、V)。 (R> MID)modify2 IF(RT << 1 | 1、中間+ 1、R、L、R、V)。 アップデート(RT)。 } ボイドは(int型のL、R INT、INT V){修正 、L + 1 - CONST INT LEN = R IF(L> 1)を変更(1、1、nは、1、1 - lenの1、* V)。 IF(L> 0 && R> = 1 && } 長い長いクエリ(INT RT、INT L、のint R、int型のL、R INT){ (L <= L && R>もし プッシュダウン(RT、R - L + 1)。 CONST INT半ば= L + R >> 1。 長い長いANS = 0; IF(L <= MID)ANS =クエリ(RT << 1、L、中間、L、R)。 ; |(1、中間+ 1、R、L、R RT << 1)(R> MID)ANS + =クエリ場合 ANSを返します。 } } INT FA [MAXN]、息子[MAXN] [2]、V [MAXN]。 #define LC(RT)息子[RT] [0] の#define RC(RT)息子[RT] [1] インラインINT GET(INT RT、INT TG = 1){戻り息子[FA [RT] [TG] == RT; } インラインブールisrootは(INT RT){リターン(0)||(RT)を取得し、RT(GET)!。} インラインボイドプッシュダウン(INT RT){V [LC(RT)] = V [RC(RT)] = V [RT]。} インラインボイド回転(INT X){ int型、Y = FA [X]、Z = FA [Y]、B =(X)を得ます。 (!isroot(Y))もし息子[Z] [取得(Y)] = xと; FAは[!息子[Y] [B] =息子[X] [B] = Y、息子[X] [!B] Yを=。 スプレイ(1)、カバー(1、V) FA [Y] = xで、FA [X] = Z; } インラインボイドスプレイ(INT X){ 静的INT S [MAXN]、トップ。 S [トップ= 1] = xと; 用(INT Y = Xの;!isroot(Y); S [++トップ] = Y = FA [Y])。 (;トップ; --top)のためにプッシュダウン(S [トップ])。 (!; isroot(x)は、(x)を回転させる)ための(!isroot(FA [X]))場合 (X)^取得(FA [X])を取得?回転(X):回転(FA [X])。 } インラインボイドカバー(int型のx、int型V){V [X] = V。} インラインボイドアクセス(int型のx、int型V){ int型のT = 0。 (X){ながら スプレイ(x)は、RC(X)= T。 SGT ::変更(V [X] - R [X] + 1、V [X] - R [FA [X]、-1); T = X、X = FA [X]。 } SGT ::(1、V 1)を修正します。 } 長い長いNUM、ANS。 INTはappend(int型のCH、int型のID){ 静的int型P、NP、Q、NQ。P = LST、NP = LST = ++ IDX、R [NP]はR [P] + = 1。 以下のための(!; P && NXT [P] [CH]; P = [P]失敗)NXT [P] [CH] = NPを。 (!pは)[NP] = 1を失敗した場合。 そうでなければ{ Q = NXT [P] [CH]。 もし(R [P] + 1 == R [Q])[NP] = Qフェイル。 他{ R [NQ = ++ IDX] = R [P] + 1。 memcpy(NXT [NQ]、NXT [Q]、26 << 2)。 用(; NXT [P] [CH] == Q; P =失敗[P])NXT [P] [CH] = NQ。 【NQ] = [Q]を失敗[Q]を失敗= [NP] = NQをフェイル。 } } NUM + = R [NP] - R [NP] [失敗]。 MNR [NP]はR [失敗[NP] + = 1。 NPを返します。 } int型のmain(){ のstd :: IOS :: sync_with_stdio(偽)のstd :: cin.tie(0)、STD :: cout.tie(0)。 のstd :: CIN >> S + 1。N = STRLEN(S + 1)。 (; iが<= N; I ++ iは1 = INT)のために POS [I] =(S [I] - [A '、I)の付加; (I 1 = int型; I <= IDX; ++ i)のためのFA [I] =失敗[I]。 (I 1 = int型++ I; iが<= N)のために{ アクセス(POS [i]は、I)。 ANS + = SGT ::クエリ(1、1、nは、I - R [POS [I] + 1、I - MNR [POS [I] + 1)。 } のstd :: COUT <<(static_castを<符号なし長い長>(NUM + 1)* NUM - 2 * ANS)/ 2 << 'の\ n'; 0を返します。 }