Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <algorithm>
- #include <vector>
- #include <iostream>
- #include <map>
- #include <set>
- using namespace std;
- typedef long long llint;
- #define pii pair< int, int >
- #define mp make_pair
- #define pb push_back
- #define lu lower_bound
- const int N = 200100;
- const int INF = 0x3f3f3f3f;
- const int LG = 19;
- const int MOD = 1000000007;
- int n;
- int q;
- int m;
- int bio[ N ];
- //0 -> nikad nije bio
- //1 -> gotov
- //2 -> aktivan
- int cycle[ N ];
- int depth[ N ];
- bool is[ N ];
- int pot2[ N ];
- vector< int > graf[ N ], veze[ N ];
- int dp[ LG ][ N ];
- int sum[ N ];
- vector< int > V;
- int which_cycle;
- inline void load( ) {
- scanf( "%d %d", &n, &m );
- for( int i = 0; i < m; i++ ) {
- int x, y;
- scanf( "%d %d", &x, &y );
- --x;
- --y;
- veze[ x ].pb( y );
- veze[ y ].pb( x );
- }
- }
- void find( int node, int par = -1 ) {
- if( bio[ node ] == 1 ) return;
- if( bio[ node ] == 2 ) {
- for( int i = ( int ) V.size( ) - 1; i >= 0; i-- ) {
- cycle[ V[ i ] ] = which_cycle;
- if( V[ i ] == node ) break;
- }
- which_cycle++;
- return;
- }
- bio[ node ] = 2;
- V.pb( node );
- for( int i = 0; i < veze[ node ].size( ); i++ ) {
- if( veze[ node ][ i ] != par ) find( veze[ node ][ i ], node );
- }
- V.pop_back( );
- bio[ node ] = 1;
- }
- inline void DEBUG1( ) {
- printf( "CIKLUSI\n" );
- for( int i = 0; i < n; i++ ) {
- printf( "node == %d -> %d\n", i + 1, cycle[ i ] );
- }
- }
- inline void find_cycles( ) {
- which_cycle = n;
- memset( cycle, -1, sizeof( cycle ) );
- find( 0 );
- //DEBUG1( );
- }
- inline void rebuild_graph( ) {
- for( int i = 0; i < n; i++ ) {
- if( cycle[ i ] == -1 ) cycle[ i ] = i, is[ i ] = true;
- }
- for( int i = 0; i < n; i++ ) {
- for( int j = 0; j < veze[ i ].size( ); j++ ) {
- int x = cycle[ i ];
- int y = cycle[ veze[ i ][ j ] ];
- if( x == y ) continue;
- graf[ x ].pb( y );
- graf[ y ].pb( x );
- }
- }
- }
- void dfs( int node, int par = -1, int dub = 0 ) {
- depth[ node ] = dub;
- if( !is[ node ] ) sum[ node ]++;
- if( par != -1 ) sum[ node ] += sum[ par ];
- dp[ 0 ][ node ] = par;
- bio[ node ] = 1;
- for( int i = 0; i < graf[ node ].size( ); i++ ) {
- if( bio[ graf[ node ][ i ] ] ) continue;
- dfs( graf[ node ][ i ], node, dub + 1 );
- }
- }
- inline void precomputation_lca( ) {
- memset( bio, 0, sizeof( bio ) );
- memset( dp, -1, sizeof( dp ) );
- dfs( cycle[ 0 ] );
- for( int j = 1; j < LG; j++ ) {
- for( int i = 0; i < n; i++ ) {
- if( dp[ j - 1 ][ i ] == -1 ) continue;
- dp[ j ][ i ] = dp[ j - 1 ][ dp[ j - 1 ][ i ] ];
- }
- }
- }
- inline int lca( int x, int y ) {
- if( depth[ x ] < depth[ y ] ) swap( x, y );
- // printf( "aa == %d %d\n", x, y );
- // for( int i = 0; i < 5; i++ ) printf( "%d ", dp[ i ][ x ] );
- // system( "pause" );
- for( int i = LG - 1; i >= 0; i-- ) {
- if( depth[ x ] - ( 1 << i ) >= depth[ y ] ) x = dp[ i ][ x ];
- }
- if( x == y ) return x;
- for( int i = LG - 1; i >= 0; i-- ) {
- if( dp[ i ][ x ] != dp[ i ][ y ] ) {
- x = dp[ i ][ x ];
- y = dp[ i ][ y ];
- }
- }
- return dp[ 0 ][ x ];
- }
- inline void precompute_pot2( ) {
- pot2[ 0 ] = 1;
- for( int i = 1; i <= n; i++ ) {
- pot2[ i ] = pot2[ i - 1 ] * 2 % MOD;
- }
- }
- inline void get_ansewer( int x, int y ) {
- int LCA = lca( x, y );
- // printf( "x, y %d %d\n", x, y );
- // printf( "LCA == %d\n", LCA );
- int ans = sum[ x ] + sum[ y ] - 2 * sum[ LCA ] + ( is[ LCA ] == 0 );
- printf( "%d\n", pot2[ ans ] );
- }
- inline void solve( ) {
- // printf( "SOLVE\n" );
- // system( "pause" );
- find_cycles( );
- // system( "pause" );
- rebuild_graph( );
- // system( "pause" );
- n *= 2;
- precomputation_lca( );
- // system( "pause" );
- precompute_pot2( );
- scanf( "%d", &q );
- // printf( "q == %d\n", q );
- for( ; q; q-- ) {
- int x, y;
- scanf( "%d %d", &x, &y );
- --x;
- --y;
- x = cycle[ x ];
- y = cycle[ y ];
- get_ansewer( x, y );
- }
- }
- int main( void ) {
- load( );
- solve( );
- // system( "pause" );
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement