KAJIMA CORPORATION CONTEST 2024(AtCoder Beginner Contest 340)(赛上A~E+G,赛后F)

我的知乎blog传送门

A~B

C

本题需要:记忆化搜索

时间复杂度< O ( l o g 2 ( n ) ) O(log^2(n)) O(log2(n))

void solve () {
   
    ll n ; cin >> n ;
    std::map < ll , ll > map ;
    auto ans = [ & ] ( auto&& ans , ll n ) -> ll {
   
        if ( n == 1 ) return 0 ;
        if ( map [ n ] ) return map [ n ] ;
        else return map [ n ] = n + ans ( ans , n / 2 ) + ans ( ans , ( n + 1 ) / 2 ) ;
    };
    cout << ans ( ans , n ) << endl ;
}

D

本题需要:最小生成树

r o o t root root 为0,建图是每个点 i i i i + 1 i + 1 i+1 x i x_i xi 连边

void solve () {
   
    ll n ; cin >> n ;
    constexpr ll inf = 1e15 ;
    vector < ll > dp ( n , inf ) ;
    priority_queue < pll , vector < pll > , greater < pll > > q ;
    q.emplace ( 0 , 0 ) ;
    std::vector < vector < pll > > map ( n ) ;
    for ( int i = 0 ; i < n - 1 ; ++ i ) {
   
        ll a , b , x ; cin >> a >> b >> x ; -- x ;
        map [ i ].emplace_back ( i + 1 , a ) ;
        map [ i ].emplace_back ( x , b ) ;
    }
    vector < bool > vis ( n ) ;
    dp [ 0 ] = 0 ;
    while ( !q.empty () ) {
   
        auto [ val , v ] = q.top () ;
        q.pop () ;
        if ( vis [ v ] ) continue ;
        dp [ v ] = val ;
        vis [ v ] = 1 ;
        for ( auto [ here , al ] : map [ v ] ) {
   
            if ( vis [ here ] ) continue ;
            if ( dp [ v ] + al < dp [ here ] ) {
   
                q.emplace ( dp [ v ] + al , here ) ;
            }
        }
    }   
    // Debug ( dp ) ;
    cout << dp.back () << endl ;
}

E

本题需要:懒标线段树

对于每一个 B i B_i Bi ,遍历到她时,读取她对于的球数 c n t cnt cnt 并把它清空,接下来把 cnt 均匀分一下, ⌊ c n t / n ⌋ \lfloor cnt/n\rfloor cnt/n 是对圈所有元素的贡献, 是对 c n t % n cnt\%n cnt%n 后面元素的贡献 (注意是圆环)

# include  <bits/stdc++.h>
# include  <ext/pb_ds/assoc_container.hpp>
# ifdef LOCAL
    # include "C:\Users\Kevin\Desktop\demo\C++_code\debug.h"
#endif
using  namespace  std ;
using  namespace  __gnu_pbds;

namespace predefine {
   
    using ll = long long ;using i64 = long long ;
    using Int = __int128 ;using pll = pair < ll , ll > ;

    # define af( i , a , b ) for ( ll i = a ; i <= b ; ++ i )
    # define df( i , a , b ) for ( ll i = a ; i >= b ; -- i )

    # define endl '\n'
}
using namespace predefine ;

//-----  板子  ---------------------------------------------------------------------------------------------------------
using Splay = tree <i64, int, less<i64>, splay_tree_tag, tree_order_statistics_node_update> ;

template < class Tag , class Info > 
struct LazySegtree {
   
	int n ;
	std::vector < Info > tree ; 
	std::vector < Tag > lazy ;
	LazySegtree (): n(0) {
   }
	LazySegtree ( const int& n , const Info& x = Info () ) {
   
		init ( n , x ) ;
	}
	template < class T >
	LazySegtree ( const std::vector < T >& v ) {
   
		init ( v ) ;
	}
	void init ( int n , const Info& x = Info () ) {
   
		init ( std::vector < Info > ( n , x ) ) ;
	}
	template < class T > 
	void init ( const std::vector < T >& v ) {
   
		n = (int)v.size () ;
        tree.assign(4 << std::__lg(n), Info());
        lazy.assign(4 << std::__lg(n), Tag());
		auto build = [ & ] ( auto&&build , int l , int r , int p ) -> void {
   
			if ( ( r - l ) == 1 ) {
   
				tree [ p ] = v [ l ] ;
				return ;
			}
			int mid = ( r + l ) >> 1 ;
			build ( build , l , mid , p << 1 ) ;
			build ( build , mid , r , p << 1 | 1 ) ;
			pull ( p ) ;
		};
		build ( build , 0 , n , 1 ) ;
	}
	void apply ( int p , const Tag& x ) {
   
		tree [ p ].apply ( x ) ;
		lazy [ p ].apply ( x ) ;
	}
	void push ( int p ) {
   
		apply ( p << 1 , lazy [ p ] ) ;
		apply ( p << 1 | 1 , lazy [ p ] );
		lazy [ p ] = Tag () ;
	}
	void pull ( int p ) {
   
		tree [ p ] = tree [ p << 1 ] + tree [ p << 1 | 1 ] ;
	}
	void range_Change ( int l , int r , const Tag& info ) {
   
		auto range_change = [ & ] ( auto&&range_change , int l , int r , int ls , int rs , int p , const Tag& info ) -> void {
   
			if ( rs <= l || r <= ls ) return ;
			if ( ls <= l && r <= rs ) {
   
				apply ( p , info );
				return ;
			}
			int mid = ( l + r ) >> 1 ;
			push ( p ) ;
			range_change 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值