luogu 3241 [HNOI2015]ショップ動的ポイントバイナリパーティション+ +ベクタ

コード: 

#include <cstdioを>   
する#include <ベクトル> 
の#include <アルゴリズム>     
の#define N 300000 
の#defineっ長い長     
の#define setIO(S)freopenは(S ".IN"、 "R"、STDIN)、freopenは(S」。アウト」、 "W"、STDOUT)
名前空間stdを使用。         
エッジをINT、N。
int型のHDに[N]、[N << 1]、NEX [N << 1]、ヴァル[N << 1]。
ボイド追加(INT U、V INT、INT C)
{ 
	NEX [++エッジ] = HD [U]、HD [U] =エッジは、[エッジ]にVが=ヴァル[エッジ]はCを=。
}   
名前空間ツリー
{    
	int型のサイズ[N]、息子[N]、トップ[N]、FA [N]、DEP [N]、DIS [N]。
	ボイドDFS1(INT U、int型FF)
	{ 
		FA [U] = FFの、サイズ[U] = 1。
		([i]はI = NEX; I I = HD [U]をint型)のための
			(![I] = FF)があれば 
			、{
				= DIS [U] +ヴァル[I] [I]に] [U] + 1、DIS = DEP [I]に] DEP。    
				([I]、Uへ)DFS1。
				サイズ[U] + =サイズ[I] [します]。
				IF(サイズ[する[I]]>サイズ[息子[U])息子[U] [I]を=。
			} 
	} 
	ボイドDFS2(INT U、INT TP)
	{ 
		トップ[U]はTPを=。
		IF(息子[U])DFS2(息子[U]、TP)。
		以下のために(int型私= HD [U]; I; I = NEX [i])と
			あれば(へ[I] =息子[U] &&へ[i]を= FA 
				[U]!!)[i]は、へへDFS2( [私]); 
	} 
	int型LCA(int型のx、int型のY)
	{ 
		一方(上面[X] = TOP [Y]!)
			DEP [TOP [X]]> DEP [トップ[Y] X = FA [TOP [X]]?: Y = FA [トップ[Y]。
		DEPを返す[X] <DEP [Y]は、x:yの。
	} 
	int型ディス(int型のx、int型Y)
	{ 
		DISを返す[X] + DIS [Y] - (DIS [LCA(X、Y)] << 1)。   
	}
}。    
{  
int型の根、SN; 
VIS int型の年齢[N]、サイズ[N]、MX [N]、[N]、Faを[N];     
構造体ノード
{ 
	int型V、D。
	TOT LL; 
	ノード(INTのV = 0、INT D = 0、LL TOT = 0):V(V)、D(D)、TOT(TOT){} 
}。  
ベクター<ノード> G [N]、F [N]。       
ブールCMP(ノードA、ノードB)
{ 
	戻りAV <BV。       
} 
ボイドgetroot(INT U、int型FF)
{ 
	サイズ[U] = 1、MX [U] = 0; 
	以下のための(int型I = HD [U]; I; I = NEX [i])と
		するif(!!の[i]を= FF && VIS [に[I]]) 
			getroot、サイズ[U([i]は、Uへ) ] + =サイズ[する[I]、MX [U] = MAX(MX [U]、[Iの大きさ[]])。
	MX [U] = MAX(MX [U]、SN-サイズ[U])。  
	IF(MX [U] <MX [ルート])ルート= U。    
}   
ボイドDFS(INT U、INT FF、INT RT、INT DEP)
	G [RT] .push_back(ノード(年齢[U]、DEP、0));   
	もし(FA [RT])F [RT] .push_back(ノード(年齢[U]、木::ディス(FA [RT]、U)、0));      
	以下のために(INT I = HD [U]; I; I = NEX [I])
	{ 
		int型V =乃至[I]。
		(V == FF || VIS [V])続けるならば、        
		DFS(V、U、RT、DEP +ヴァル[I])。     
	}   
} 
ボイドが解決する(INT U)
{   
	VIS [U] = 1。  
	G [U] .push_back(ノード(-100,0,0))。
	F [U] .push_back(ノード(-100,0,0))。
	G [U] .push_back(ノード(1000000004,0,0))。    
	F [U] .push_back(ノード(1000000004,0,0))。            
	DFS(U 0、U、0);                      
	ソート(G [U] .begin()、G [U] .END()、CMP)。
	ソート(F [U] .begin()、F [U] .END()、CMP)。  
	F [U] [i]は.tot = F [U] [I-1] .tot + 1LL * F [U](++ I; Iは、F [U] .size()<I 1 = INT)のために[I] .D。      
	以下のために(INT i = 1; iはGを<U] .size(); ++ I)G [U] [i]は.tot = G [U] [I-1] .tot + 1LL * G [U] [I] .D。      
	(; I I = NEX [i]の値int i = HD [U])のための
		(!VIS [する[I])であれば
		{ 
			SN =サイズ、根= 0、getroot(の[I [I]乃至] ]、U)・FA [ルート] = Uは、(ルート)を解きます。      
		} 
} 
(int型のL、R INT、INT U)動作っ
{    
	LL再= 0。
	int型のL、R、中間、ANS1 = 0、ANS2 = 0。  
	L = 0、R = G [U] .size() - 1; 
	一方、(L <= R)
	{ 
		半ば=(L + R)>> 1。     
		IF(G [U] [中間] .V> = L)ANS1 =中間、R =ミッド1。
		他リットル=ミッド+ 1;  
	}     
	、L = 0、R = G [U] .size() - 1; 
	一方、(L <= R)
	{ 
		半ば=(L + R)>> 1。
		IF(G [U] [中間] .V <= R)ANS2 =中間、L =ミッド+ 1。
		他に、R =半ば1;    
	}   
	IF(ANS1> 0 && ANS2 <G [U] .size() - 1 && ANS1 <= ANS2)
		再+ = G [U] [ANS2] .tot-G [U] [ans1-1] .tot。    
	int型U = U;          
	用(; Faを[U]; U = Faを[U])
	{ 
		int型anss1 = ANS1、anss2 = ANS2。        
		L = 0、R = G [Faを[U]サイズ() - 1、ANS1 = 0。   
		一方、(L <= R)
		{ 
			半ば=(L + R)>> 1。     
			IF(G [Faを[U] [中間] .V> = L)ANS1 =中間、R =ミッド1。
			他リットル=ミッド+ 1;  
		}     
		、L = 0、R = G [Faを[U]サイズ() - 1、ANS2 = 0。      
		一方、(L <= R)
		{ 
			半ば=(L + R)>> 1。
			IF(G [Faを[U] [中間] .V <= R)ANS2 =中間、L =ミッド+ 1。
			他に、R =半ば1;    
		}      
		IF(ANS1> ANS2)続けます。  
		TMP + = G [Faを[U] [ANS2] .tot-G [Faを[U] [ans1-1] .tot。  
		IF(anss2> = anss1)tmp- = F [U] [anss2] .tot-F [U] [anss1-1] .tot。                          
		IF(anss1 <= anss2)
			TMP = TMP +(LL)(ANS2-ans1-(anss2-anss1 + 1)+1)* 1LL *ツリー::ディス(U・FA [U])。                      
			TMP = TMP +(LL)(ANS2、ANS1 + 1)* 1LL *ツリー::ディス(U・FA [U])。    
		+ = tmpの再;     
	} 
	戻り再。                        
} 
int型のmain()
{ 
	// setIO( "入力")。   
	int型Q、A、I、J。
	scanf関数( "%D%D%D"、&N、&Q&A)。
	scanf関数( "%dの"、および年齢[I])は、(i ++; iが<= N I = 1)のために、           
	(++ I; iがn <I = 1)のために
	{ 
		A、B、C INT。
		scanf関数( "%D%D%D"、&、&
		(A、Bは、C)、追加(B、C)。
	ツリー:: DFS2(1,1); 
	MX [0] = SN = N、getroot(1,0)、(ルート)を解きます。         
	LL lastans = 0。
	用(int型CAS = 1; CAS <= Q; ++ CAS)
	{ 
		int型、U、A、B、L、R。
		scanf関数( "%D%D%D"、U、及び、・B&)。            
		L =(A + lastans)%A、R =(B + lastans)%のA。
		IF(L> R)スワップ(L、R)。        
		printf( "%LLDする\ n"、lastans =仕事(L、R、U))。   
	}    
	0を返します。
}

  

おすすめ

転載: www.cnblogs.com/guangheli/p/11448981.html