異なるデジタルの数の間隔を求めて木の会長

異なるデジタルの数の間隔を求めて木の会長

例:[SDOI2009] HHネックレスは(ただし、私は木の社長は、とにかく72ポイントにデータカードを強化されます)

トピック取り扱い:

構成美しい貝殻の様々なからHH文字列のネックレス。HHは異なるシェルは幸運をもたらすと信じているので、すべての散歩の後、彼は、彼らが表現する意味を考えて、しばらくアウトシェルに無料となります。HHは、常に新しいシェルを集めるので、彼は長いネックレスを取得しています。シェルの一定期間、どのように多くの異なったシェルを含む:ある日、彼は突然問題を提起しますか?ネックレスは長すぎるので、この質問は......答えることは困難です。そこで彼は、この問題を解決するために、賢明なあなたを助けるために持っていました。

最初のライン:整数N、ネックレスの長さ。

第二行順次を表すNの整数(番号付けは0から1000000の間の整数である)ネックレスシェルを表します。

第三行:整数Mは、数HH問い合わせを表します。

次のM行:各行二つの整数、L及びR(1つの≤Lの≤のR≤のN)、間隔照会を表します。

問題解決のためのアイデア

同じ番号で、その第1の位置との前に最後のレコードと各数値のために我々は、そうでない場合、次いで、0と称します。
各葉ノードは、次に、議長ツリーは、このリーフノード番号に対応する格納されているI最後の数です。

その後、通常の会長ツリー(CZは、データカードを強化することでした)

バージョン1:65ポイント
cpp #include<cstdio> #include<queue> #include<cctype> #include<cstring> #include<algorithm> using namespace std ; const int MAXN = 1000005 ; inline int read(){ int s=0 ; char g=getchar() ; while(g>'9'||g<'0')g=getchar() ; while( g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ; } struct Seg{ int l , r , sum ; }t[ MAXN<<5 ]; int a[ MAXN ] , last[ MAXN ] , b[ MAXN ] , root[ MAXN ] , N , M , ma=0 , cnt = 0 ; void copyNode( int x , int y ){ t[ x ].l = t[ y ].l , t[ x ].r = t[ y ].r , t[ x ].sum = t[ y ].sum+1 ; } void build( int p , int l , int r ){ t[ p ].sum = 0 ; if( l ==r )return ; int mid = ( l+r )>>1 ; build( t[ p ].l = ++cnt , l , mid ) ; build( t[ p ].r = ++cnt , mid+1 , r ) ; } int New_made( int las , int l , int r , int val ){ int p = ++cnt ; copyNode( p , las ) ; if( l == r )return p ; int mid = ( l+r )>>1 ; if( val <= mid )t[ p ].l = New_made( t[ p ].l , l , mid , val ) ; else t[ p ].r = New_made( t[ p ].r , mid+1 , r , val ) ; return p ; } int ask( int x , int y , int l , int r , int ll ,int rr ){ if( l >= ll && r <= rr )return t[ x ].sum - t[ y ].sum ; int mid = ( l+r )>>1 ; int val = 0 ; if( ll <= mid )val = ask( t[ x ].l , t[ y ].l , l , mid , ll , rr ) ; if( rr > mid )val += ask( t[ x ].r , t[ y ].r , mid+1 , r , ll , rr ) ; return val ; } /*void Debug( int p , int p2 , int l , int r ){ if( l == r ){ printf("%d ",t[ p ].sum - t[ p2 ].sum ) ; return ; } int mid = (l+r )>>1 ; Debug( t[ p ].l , t[ p2 ].l , l , mid ); Debug( t[ p ].r , t[ p2 ].r , mid+1 , r ); }*/ int main(){ N = read() ; for( int i = 1 ; i <= N ; ++i ) a[ i ] = read() , last[ i ] = b[ a[ i ] ] , b[ a[ i ] ] = i , ma = max( last[ i ] , ma ) ; M = read() ; build( root[0] = ++cnt , 0 , ma ) ;//0~ma for( int i = 1 ; i <= N ; ++i )root[ i ] = New_made( root[ i-1 ] , 0 , ma , last[ i ] ) ; int m1 , m2 ; for( int i = 1 ; i <= M ; ++i ){ m1 = read() , m2 = read() ; printf("%d\n",m2 - m1 + 1 - ask( root[ m2 ] , root[ m1-1 ] , 0 , ma , m1 , m2 ) ) ; } //Debug( root[ 99 ] , root[ 14 ] , 0 , ma ) ; return 0 ; } 

バージョンII:72分
cpp #include<cstdio> #include<queue> #include<cctype> #include<cstring> #include<algorithm> using namespace std ; const int MAXN = 1000005 ; inline int read(){ int s=0 ; char g=getchar() ; while(g>'9'||g<'0')g=getchar() ; while( g>='0'&&g<='9')s=s*10+g-'0',g=getchar() ; return s ; } struct Seg{ int l , r , sum ; }t[ MAXN<<5 ]; int a[ MAXN ] , last[ MAXN ] , b[ MAXN ] , root[ MAXN ] , N , M , ma=0 , cnt = 0 ; void copyNode( int x , int y ){ t[ x ].l = t[ y ].l , t[ x ].r = t[ y ].r , t[ x ].sum = t[ y ].sum+1 ; } void build( int p , int l , int r ){ t[ p ].sum = 0 ; if( l ==r )return ; int mid = ( l+r )>>1 ; build( t[ p ].l = ++cnt , l , mid ) ; build( t[ p ].r = ++cnt , mid+1 , r ) ; } int New_made( int las , int l , int r , int val ){ int p = ++cnt ; copyNode( p , las ) ; if( l == r )return p ; int mid = ( l+r )>>1 ; if( val <= mid )t[ p ].l = New_made( t[ p ].l , l , mid , val ) ; else t[ p ].r = New_made( t[ p ].r , mid+1 , r , val ) ; return p ; } int ask( int x , int y , int rr, int l ,int r ){ if( r <= rr)return t[ x ].sum - t[ y ].sum ; int mid=(l+r)>>1 , val = ask(t[ x ].l , t[ y ].l , rr, l , mid ); if( mid < rr )val+=ask(t[ x ].r , t[y].r , rr , mid+1 , r ); return val; } /*void Debug( int p , int p2 , int l , int r ){ if( l == r ){ printf("%d ",t[ p ].sum - t[ p2 ].sum ) ; return ; } int mid = (l+r )>>1 ; Debug( t[ p ].l , t[ p2 ].l , l , mid ); Debug( t[ p ].r , t[ p2 ].r , mid+1 , r ); }*/ int main(){ N = read() ; for( int i = 1 ; i <= N ; ++i ) a[ i ] = read() , last[ i ] = b[ a[ i ] ] , b[ a[ i ] ] = i , ma = max( last[ i ] , ma ) ; M = read() ; build( root[0] = ++cnt , 0 , ma ) ;//0~ma for( int i = 1 ; i <= N ; ++i )root[ i ] = New_made( root[ i-1 ] , 0 , ma , last[ i ] ) ; int m1 , m2 ; for( int i = 1 ; i <= M ; ++i ){ m1 = read() , m2 = read() ; printf("%d\n",ask( root[ m2 ] , root[ m1-1 ] , m1-1 , 0 , ma ) ) ; } //Debug( root[ 99 ] , root[ 14 ] , 0 , ma ) ;5831587 2793261 return 0 ; }

おすすめ

転載: www.cnblogs.com/ssw02/p/11391428.html