每日练习2021.9.22
题目:
1. ZOJ 3261
2. HDU 4725
3. BZOJ 4052
1. ZOJ 3261 Connections in Galaxy War
思路很简单,将询问离线下来反向操作,将删边转化为加边,就可以使用并查集简单处理了。本题和洛谷P1197几乎是相同的。 代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e4 + 10; 4 int fa[ maxn ], rnk[ maxn ]; 5 int find( int x ) { 6 if ( x == fa[ x ] ) return x; 7 return fa[ x ] = find( fa[ x ] ); 8 } 9 void merge( int x, int y ) { 10 x = find( x ), y = find( y ); 11 if ( x == y ) return; 12 if ( rnk[ x ] < rnk[ y ] ) 13 fa[ x ] = y; 14 else if ( rnk[ x ] > rnk[ y ] ) 15 fa[ y ] = x; 16 else 17 fa[ max( x, y ) ] = min( x, y ); 18 } 19 int n, m, t; 20 struct Q { 21 int op, x, y; 22 } q[ maxn * 5 ]; 23 int ans[ maxn * 5 ]; 24 struct edge { 25 int u, v, hs; 26 } e[ maxn * 2 ]; 27 unordered_map< int, int > bk; 28 29 int main( ) { 30 int T = 0; 31 while ( cin >> n ) { 32 if ( T++ ) cout << '\n'; 33 bk.clear( ); 34 for ( int i = 0; i < n; i++ ) { 35 fa[ i ] = i; 36 cin >> rnk[ i ]; 37 } 38 cin >> m; 39 for ( int i = 1; i <= m; i++ ) { 40 int u, v; 41 cin >> u >> v; 42 if ( u > v ) swap( u, v ); 43 e[ i ] = edge { u, v, 100000 * u + v }; 44 } 45 cin >> t; 46 for ( int i = 1; i <= t; i++ ) { 47 string str; 48 cin >> str; 49 if ( str[ 0 ] == 'q' ) { 50 q[ i ].op = q[ i ].y = 0; 51 cin >> q[ i ].x; 52 } else { 53 q[ i ].op = 1; 54 int u, v; 55 cin >> u >> v; 56 if ( u > v ) swap( u, v ); 57 q[ i ] = Q { 1, u, v }; 58 bk[ 100000 * u + v ] = 1; 59 } 60 } 61 for ( int i = 1; i <= m; i++ ) { 62 int u = e[ i ].u, v = e[ i ].v; 63 if ( ! bk[ e[ i ].hs ] ) merge( u, v ); 64 } 65 int tot = 0; 66 for ( int i = t; i >= 1; i-- ) { 67 if ( q[ i ].op == 0 ) { 68 if ( rnk[ find( q[ i ].x ) ] <= rnk[ q[ i ].x ] ) 69 ans[ ++tot ] = -1; 70 else 71 ans[ ++tot ] = find( q[ i ].x ); 72 } else { 73 merge( q[ i ].x, q[ i ].y ); 74 } 75 } 76 for ( int i = tot; i >= 1; i-- ) 77 cout << ans[ i ] << '\n'; 78 } 79 return 0; 80 }
2. HDU 4725 The Shortest Path in Nya Graph
在每层添加两个超级源点,分别作为每层的源点和汇点,边权为0,然后跑dijkstra,如果只添加一个,那么每层所有点之间的最短路就变成了0,假了
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 3e5 + 10; 4 5 struct node { 6 int to, w; 7 }; 8 vector< node > G[ maxn ]; 9 void add( int u, int v, int w ) { 10 G[ u ].push_back( node { v, w } ); 11 } 12 struct hnode { 13 int d, u; 14 bool operator<( const hnode &x ) const { 15 return d > x.d; 16 } 17 }; 18 int d[ maxn ], vis[ maxn ]; 19 int n, m, c; 20 21 22 void dijkstra( ) { 23 memset( d, 0x3f, sizeof( d ) ); 24 memset( vis, 0, sizeof( vis ) ); 25 d[ 1 ] = 0; 26 priority_queue< hnode > q; 27 q.push( hnode { 0, 1 } ); 28 while ( ! q.empty( ) ) { 29 int u = q.top( ).u; 30 q.pop( ); 31 if ( vis[ u ] ) continue; 32 vis[ u ] = 1; 33 for ( int i = 0; i < G[ u ].size( ); i++ ) { 34 node e = G[ u ][ i ]; 35 if ( d[ e.to ] > d[ u ] + e.w ) { 36 d[ e.to ] = d[ u ] + e.w; 37 q.push( hnode { d[ e.to ], e.to } ); 38 } 39 } 40 } 41 } 42 43 int main( ) { 44 ios::sync_with_stdio( false ); 45 cin.tie( nullptr ), cout.tie( nullptr ); 46 int T, kse = 1; 47 cin >> T; 48 while ( T-- ) { 49 cin >> n >> m >> c; 50 for ( int i = 1; i < maxn; i++ ) 51 G[ i ].clear( ); 52 for ( int i = 1; i <= n; i++ ) { 53 int x; 54 cin >> x; 55 add( x + n, i, 0 ), add( i, x + n * 2, 0 ); 56 } 57 for ( int i = 1; i <= m; i++ ) { 58 int u, v, w; 59 cin >> u >> v >> w; 60 add( u, v, w ), add( v, u, w ); 61 } 62 for ( int i = 1; i < n; i++ ) { 63 add( i + n * 2, i + 1 + n, c ); 64 add( i + 1 + n * 2, i + n, c ); 65 } 66 dijkstra( ); 67 cout << "Case #" << kse++ << ": "; 68 if ( d[ n ] == 0x3f3f3f3f ) 69 cout << "-1\n"; 70 else 71 cout << d[ n ] << '\n'; 72 } 73 return 0; 74 }
3. BZOJ 4052 Magical GCD
和HDU 5726差不多,随手写了个st表+二分,数据比较水,除了老毛子的OJ都没被卡掉,先就这样吧 >__<
1 #include <bits/stdc++.h> 2 using namespace std; 3 constexpr int maxn = 1e5 + 10; 4 typedef long long ll; 5 ll st[ maxn ][ 20 ]; 6 int Log[ maxn ]; 7 ll n; 8 inline ll read( ) { 9 ll x = 0; 10 char ch = getchar( ); 11 while ( ch < '0' || ch > '9' ) 12 ch = getchar( ); 13 while ( ch >= '0' && ch <= '9' ) 14 x = x * 10 + ch - 48, ch = getchar( ); 15 return x; 16 } 17 ll query( int l, int r ) { 18 int k = Log[ r - l + 1 ]; 19 return __gcd( st[ l ][ k ], st[ r - ( 1 << k ) + 1 ][ k ] ); 20 } 21 int main( ) { 22 Log[ 1 ] = 0, Log[ 2 ] = 1; 23 for ( int i = 3; i < maxn; i++ ) 24 Log[ i ] = Log[ i / 2 ] + 1; 25 ll _ = read( ); 26 while ( _-- ) { 27 n = read( ); 28 for ( int i = 1; i <= n; i++ ) { 29 st[ i ][ 0 ] = read( ); 30 } 31 32 for ( int j = 1; j <= 17; j++ ) { 33 for ( int i = 1; i + ( 1 << j ) - 1 <= n; i++ ) 34 st[ i ][ j ] = 35 __gcd( st[ i ][ j - 1 ], st[ i + ( 1 << j - 1 ) ][ j - 1 ] ); 36 } 37 38 ll ans = -1; 39 for ( int i = 1; i <= n; i++ ) { 40 int j = i; 41 while ( j <= n ) { 42 ll x = query( i, j ); 43 int l = j, r = n + 1; 44 while ( r - l > 1 ) { 45 int mid = ( r + l ) >> 1; 46 if ( query( i, mid ) == x ) 47 l = mid; 48 else 49 r = mid; 50 } 51 ans = max( ans, ( l - i + 1 ) * query( i, l ) ); 52 j = l + 1; 53 } 54 } 55 printf( "%lld\n", ans ); 56 } 57 return 0; 58 }

浙公网安备 33010602011771号