まず、宣言そのイタリア:
N、A、B、2行の問い合わせ間隔[L1、R1]、[L2、R2]の1つのアレイは、これら二つの領域の同じ番号の数を見つけます。
ソリューション:
我々は、参照番号、[i]を表し、Bの対応するビットのi番目の位置としたいです。
これは区間である[L1、R1]クエリ内の値の数[L2、R2]です。
重量は、ツリーラインの考えることは難しいことではありません、それは永続することができ、これで完了です!!!
コードを見てください:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型 MAXN = 1E6 + 10 。 構造体ノード{ int型のVal、L、R。 } TR [MAXN * 25 ]。 整数N、M、[MAXN]、根[MAXN]、TI。 インラインint型リード(){ int型のx = 0、F = 1。チャー C = GETCHAR()。 一方、(C < ' 0 ' || C> ' 9 '){ もし、(C == ' - ')、F = - 1; C = GETCHAR();} 一方、(C> = ' 0 ' && C <= ' 9 '){X =(X << 1)+(X << 3)+ C- ' 0 ' ; C = GETCHAR( );} 戻り X * F。 } インラインINTビルド(int型 L、INT R){ int型、T = ++ TI。 もし(L == R)戻りT。 INTの半ば=(L + R)>> 1 。 TR [T] .L = ビルド(L、MID)。 TR [T] .R =ビルド(ミッド+1 、R)。 リターントン。 } インラインINT変更(INT H、INT L、INT R、INT X){ int型、T = ++ TI。 TR [T] = T R [H]。 TR [T] .val ++ ; もし(L == R)戻りT。 INTの半ば=(L + R)>> 1 。 もし(MID> = X)TR [T] .L = 修正(TR [T] .L、L、中、X)。 他の TR [T] .R =修正(TR [T] .R、中間+ 1 、R、X)。 リターントン。 } int型lastans; インラインint型メーク(INT X){ リターン(X + lastans- 1)%N + 1 。 } インラインINTクエリ(INT H、INT L、INT R、int型のx、int型Y){ 場合(L> Y || rは<x)を返す 0 。 場合(L> = X && R <= Y)戻りTR [H] .val。 INTの半ば=(L + R)>> 1 。 戻りクエリ(TR [H] .L、L、中、X、Y)+クエリ(TR [H] .R、中間+ 1 、R、X、Y)。 } int型メイン(){ N = (読み取り) 用(INTは iは= 1 ++ I; <I = N ) [リード()] = I。 ルート[ 0 ] =ビルド(1 、N) 以下のために(INT iが= 1 ; iが<= N; I ++ ) ルート[I] =修正(ルート[I- 1 ]、1 、nは、[読み取り()])。 M = )(読み取ります。 int型のA、B、C、D; int型L1、L2、R1、R2; 以下のために(INT iは= 1 ; I <= M; I ++ ){ A=リード()、B =(読み取り= C、)(読み取り)、D = (読み取り) L1 = 分(メイク()、メイク(b)参照)。 R1 = MAX(メイク()、メイク(b)参照)。 L2 = 分(メイク(C)、メイク(d)参照)。 R2 = MAX(メイク(C)、メイク(d)参照)。 lastans =クエリ(ルート[R2]、1、nは、L1、R1)-query([L2-ルート1 ]、1、nは、L1、R1)+ 1 。 printf(" %dの\ n "、lastans- 1 )。 } 戻り 0 。 }
深く小さくて弱いと感じました。