每日练习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 }

 

posted @ 2021-09-22 21:58  Vinicilia  阅读(72)  评论(0)    收藏  举报