CF323C二つの順列

まず、宣言そのイタリア:

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 
}

深く小さくて弱いと感じました。

おすすめ

転載: www.cnblogs.com/syzf2222/p/12555896.html