Chairman of the tree seeking the interval of the number of different digital

Chairman of the tree seeking the interval of the number of different digital

Example: [SDOI2009] HH necklace (However, I will be the President of the trees anyway strengthen data cards to 72 points)

Topic Handling:

HH string necklace from a variety of beautiful shells composed. HH believe different shells to bring good luck, so after every walk, he will be free to shell out a while, thinking the meaning they express. HH constantly collecting new shell, so he's getting longer necklace. One day, he suddenly raises the question: a certain period of shells, including how many different shells? This question is difficult to answer ...... because the necklace is too long. So he had to help you wise, to solve this problem.

The first line: an integer N, the length of the necklace.

Second line: N integers representing sequentially represents necklace shell (numbering is an integer between 0 and 1000000).

Third row: an integer M, represents the number HH inquiry.

Next M rows: each row two integers, L and R (1 ≤ L ≤ R ≤ N), representing the interval inquiry.

Problem-solving ideas

We For each number with the last record in front of its first position and which is the same number, if not, then referred to as a 0.
Each leaf node is then Chairman tree is stored corresponding to this leaf node number is the number of the last i.

Then, an ordinary Chairman tree (CZ was to strengthen data card)

Version 1: 65 points
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 ; } 

Version II: 72 minutes
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 ; }

Guess you like

Origin www.cnblogs.com/ssw02/p/11391428.html