Advertisement
BoxerTC

Component Tree

Oct 29th, 2014
407
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.80 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define sc( x ) scanf( "%d" , &x )
  5. #define REP( i , n ) for( int i = 0 ; i < n ; ++i )
  6. #define FOR(it,A) for(typeof A.begin() it = A.begin(); it!=A.end(); it++)
  7. #define clr( t , val ) memset( t , val , sizeof( t ) )
  8.  
  9. #define pb push_back
  10. #define all( v ) v.begin() , v.end()
  11. #define SZ( v ) ((int)(v).size())
  12.  
  13. #define mp make_pair
  14. #define fi first
  15. #define se second
  16.  
  17. #define N 300000
  18.  
  19. typedef vector< int > vi;
  20. typedef vector< string > vs;
  21.  
  22. struct FT {
  23.     vi T;
  24.     vi id;
  25.     int len;
  26.     int MAXVAL;
  27.     FT() {}
  28.     FT( int x , vi &vec ) {
  29.         MAXVAL = x + 1;
  30.         len = x;
  31.         T = vi( MAXVAL + 1 );
  32.         id = vec;
  33.     }
  34.     void Update( int pos , int val ) { update( pos + 1 , val ); }
  35.     void update( int pos , int val ) {
  36.         while( pos <= MAXVAL ){
  37.             T[ pos ] += val;
  38.             pos += pos & -pos;
  39.         }
  40.     }
  41.     int get2( int lo , int hi ) { return Query( hi ) - Query( lo - 1 ); }
  42.     int Query( int pos ){ return query( pos + 1 );}
  43.     int query( int pos ) {
  44.         int sum = 0;
  45.         while( pos ){
  46.             sum += T[ pos ];
  47.             pos -= pos & -pos;
  48.         }
  49.         return sum;
  50.     }
  51.     int getFirst( int end ){
  52.         int lo = 0 , hi = end;
  53.         if( Query( lo ) == Query( hi ) ) return id[ lo ];
  54.         while( hi - lo > 1 ){
  55.             int med = (lo + hi) >>1;
  56.             if( Query( med ) == Query( hi ) ) hi = med;
  57.             else lo = med;
  58.         }
  59.         return id[ hi ];
  60.     }
  61. } st[ N + 5 ];
  62.  
  63. int chain[ N + 5 ] , tam[ N + 5 ] , h[ N + 5 ] , p[ N + 5 ];
  64.  
  65. int n ;
  66. int peso[ N + 5 ];
  67. int csz , cola[ N + 5 ];
  68. vi E[ N + 5 ];
  69.  
  70. int querynodos( int u , int v ) {
  71.     int sum = 0;
  72.     while( chain[ u ] != chain[ v ] ) {
  73.         if( h[ chain[ u ]]  < h[ chain[ v ] ]) swap( u , v );
  74.         int c = chain[ u ] , len = st[ c ].len;
  75.         sum += st[ c ].get2( 0 , h[ u ] - h[ c ] );
  76.         u = p[ chain[ u ] ];
  77.     }
  78.     if( h[ u ] < h[ v ] ) swap( u , v );
  79.     int c = chain[ u ] , len = st[ c ].len;
  80.     sum += st[ c ].get2( h[ v ] - h[ c ] , h[ u ] - h[ c ] );
  81.     return sum;
  82. }
  83. int up( int u ){
  84.     while( 1 ) {
  85.         int c = chain[ u ] , len = st[ c ].len;
  86.         if( st[ c ].get2( 0 , h[ u ] - h[ c ] ) ){
  87.             return st[ c ].getFirst( h[ u ] - h[ c ] );
  88.         }else u = p[ chain[ u ] ];
  89.     }
  90. }
  91. void parse( string s , string &key , string &value ){
  92.     int pos = s.find( "=" );
  93.     key = s.substr( 0 , pos ) , value = s.substr( pos + 1 );
  94. }
  95. struct comp{
  96.     vs keys , values;
  97.     int id , p;
  98.     comp(){}
  99.     comp( int id , int p , vs keys , vs values ) : id( id ) , p( p ) , keys( keys ) , values( values ) {}
  100. };
  101. struct event{
  102.     int u , idQ;
  103.     event( int u , int idQ ) : u( u ) , idQ( idQ ) {}
  104. };
  105. int getId( vs &vec , string s ){ return lower_bound( all( vec ) , s ) - vec.begin();}
  106.  
  107. int main(){
  108.     ios_base :: sync_with_stdio( 0 );
  109.     while( cin >> n ){
  110.         REP( i , N ) E[ i ].clear();
  111.         vs allKeys;
  112.         vector< comp > components( n );
  113.         REP( v , n ) {
  114.             int u , len;
  115.             cin >> u >> len;
  116.             u --;
  117.             if( u >= 0 ){
  118.                 E[ u ].pb( v );
  119.                 E[ v ].pb( u );
  120.             }
  121.             vs keys , values;
  122.             vector< pair< string , string > > vec;
  123.             REP( i , len ){
  124.                 string s;
  125.                 cin >> s;
  126.                 string key , value;
  127.                 parse( s , key , value );
  128.                 vec.pb( mp( key , value ) );
  129.                 allKeys.pb( key );
  130.             }
  131.             sort( all( vec ) );
  132.             REP( i , SZ( vec ) ) keys.pb( vec[ i ].fi ) , values.pb( vec[ i ].se );
  133.             components[ v ] = comp( v , u , keys , values );
  134.         }
  135.         sort( all( allKeys ) );
  136.         allKeys.resize( unique( all( allKeys ) ) - allKeys.begin() );
  137.  
  138.         vector< vi > ev1( SZ( allKeys ) );
  139.         REP( i , n ){
  140.             int p = components[ i ].p ;
  141.             vs keys = components[ i ].keys , values = components[ i ].values;
  142.             REP( j , SZ( keys ) ){
  143.                 int id = getId( allKeys , keys[ j ] );
  144.                 ev1[ id ].pb( i );
  145.             }
  146.         }
  147.  
  148.         clr( p , -1 );
  149.         csz = 0;
  150.         cola[ csz++ ] = 0;
  151.         p[ 0 ] = 0;
  152.         h[ 0 ] = 0;
  153.         REP( i , csz ) {
  154.             int u = cola[ i ];
  155.             FOR( e , E[ u ] ) {
  156.                 int v = *e;
  157.                 if ( ~p[ v ] ) continue;
  158.                 cola[ csz++ ] = v;
  159.                 p[ v ] = u;
  160.                 h[ v ] = h[ u ] + 1;
  161.             }
  162.         }
  163.         for( int i = csz - 1 ; i >= 0 ; --i ) {
  164.             int u = cola[ i ];
  165.             tam[ u ] = 1;
  166.             FOR( e , E[ u ] ) {
  167.                 int v = *e;
  168.                 if( p[ u ] == v ) continue;
  169.                 tam[ u ] += tam[ v ];
  170.             }
  171.         }
  172.         clr( chain , -1 );
  173.         REP( i , csz ) {
  174.             int u = cola[ i ];
  175.             if ( ~chain[ u ] ) continue;
  176.             chain[ u ] = u;
  177.             int v = u;
  178.             while( 1 ) {
  179.                 int next = -1;
  180.                 FOR( v , E[ u ] ) if( p[ *v ] == u )
  181.                     if ( next ==-1 || tam[ next ] < tam[ *v ] ) next = *v;
  182.                 if( next == -1 ) break;
  183.                 chain[ next ] = chain[ u ];
  184.                 u = next;
  185.             }
  186.             int len = h[ u ] - h[ v ] + 1;
  187.             vi id( len );
  188.            
  189.             REP( i , len ) {
  190.                 id[ i ] = u;
  191.                 u = p[ u ];
  192.             }
  193.             reverse( all( id ) );
  194.             st[ v ] = FT( len , id );
  195.         }
  196.         int Q;
  197.         cin >> Q;
  198.         vector< vector< event > > ev2( SZ( allKeys ) );
  199.  
  200.         REP( q , Q ) {
  201.             int u;
  202.             string key;
  203.             cin >> u >> key;
  204.             cout << "";
  205.             u -- ;
  206.             if( !binary_search( all( allKeys ) , key ) ) continue;
  207.             int id = getId( allKeys , key );
  208.             ev2[ id ].pb( event( u , q ) );
  209.             /*
  210.             if( op == 'I' ) {
  211.                 scanf( "%d%d" , &u , &v ); u--;//// increment in v to u
  212.                 int c = chain[ u ] , len = st[ c ].len;
  213.                 st[ c ].update( h[ u ] - h[ c ] , v );
  214.             }else {
  215.                 scanf("%d%d", &u, &v); u-- , v--;
  216.                 int ans = querynodos( u , v );
  217.                 printf( "%d\n" , ans );
  218.             }
  219.             */
  220.         }
  221.         /*
  222.         cout << "CHAINS" << endl;
  223.         REP( i , n ) cout << chain[ i ] << " ";
  224.         cout << endl;
  225.         */
  226.         /*
  227.         REP( i , SZ( ev2 ) ) {
  228.             REP( j , SZ( ev2[ i ] ) ) cout << "( " << ev2[ i ][ j ].u << " , " << ev2[ i ][ j ].idQ << " ) ";
  229.             cout << endl;
  230.         }
  231.         */
  232.         vs ans( Q , "N/A" );
  233.        
  234.         REP( i , SZ( ev1 ) ) {
  235.             /*
  236.             cout << allKeys[ i ] << " :: ";
  237.             REP( j , SZ( ev1[ i ] ) ) cout << ev1[ i ][ j ] << " ";
  238.             cout << endl;
  239.             */
  240.             REP( j , SZ( ev1[ i ] ) ) {
  241.                 int u = ev1[ i ][ j ] ;
  242.                 int c = chain[ u ];
  243.                 /*
  244.                 cout << u << " " << c << endl;
  245.                 cout << h[ u ] << " " << h[ c ] << " " << st[ c ].len << endl;
  246.                 */
  247.                 st[ c ].Update( h[ u ] - h[ c ] , +1 );
  248.             }
  249.             /*
  250.             REP( j , n ) cout << querynodos( j , j ) << " ";
  251.             cout << endl;
  252.             cout << "len queries " << SZ( ev2[ i ] ) << endl;
  253.             */
  254.             REP( j , SZ( ev2[ i ] ) ){
  255.                 int u = ev2[ i ][ j ].u , idQ = ev2[ i ][ j ].idQ;
  256.                 if( querynodos( 0 , u ) == 0 ) continue;
  257.                 int v = up( u );
  258.                 //cout << "beg : " << u << "   end : " << v << endl ;
  259.                 int id = getId( components[ v ].keys , allKeys[ i ] );
  260.                 /*
  261.                 cout << "target = " << allKeys[ i ] << endl;
  262.                 REP( k , SZ( components[ v ].keys ) ) cout << components[ v ].keys[ k ] << " ";
  263.                 cout << endl;
  264.                 */
  265.                 //cout << "id : " << id << " contains : " << components[ v ].keys[ id ] << endl;
  266.                 ans[ idQ ] = components[ v ].values[ id ];
  267.             }
  268.            
  269.             REP( j , SZ( ev1[ i ] ) ) {
  270.                 int u = ev1[ i ][ j ] ;
  271.                 int c = chain[ u ];
  272.                 st[ c ].Update( h[ u ] - h[ c ] , -1 );
  273.             }
  274.            
  275.         }
  276.        
  277.         REP( i , SZ( ans ) ) {
  278.             cout << ans[ i ] << '\n';
  279.             //fflush(stdout);
  280.         }
  281.        
  282.     }
  283. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement