zoukankan      html  css  js  c++  java
  • [BZOJ 5123][Lydsy1712月赛]线段树的匹配

    Description

    题库链接

    给你一棵区间为 ([1,n]) 的线段树,求这棵树的最大匹配以及对应的方案数,取模。

    (1leq nleq 10^{18})

    Solution

    (f_{n,1/0}) 表示区间长度为 (n) 时,所对应的子树根节点选或不选时的最大匹配,(g_{n,1/0}) 表示取对应的最大值时的方案数。

    容易发现长度为 (n) 的状态只会由 (leftlfloorfrac{n}{2} ight floor)(n-leftlfloorfrac{n}{2} ight floor) 转移过来。

    那么直接开 ( ext{map}) 存即可,状态数是 (O(log(n))) 的。

    Code

    #include <bits/stdc++.h>
    #define ll long long
    #define CAL(x) cal(f[0][x], f[1][x], g[0][x], g[1][x])
    using namespace std;
    const int yzh = 998244353;
    
    map<ll, ll> f[2];
    map<ll, int> g[2];
    ll n;
    
    int cal(ll a, ll b, int c, int d) {
        if (a == b) return (c+d)%yzh;
        return a > b ? c : d;
    }
    void dp(ll n) {
        if (g[0].count(n)) return;
        ll lx, ly;
        dp(lx = n/2); dp(ly = n-lx);
        
        f[0][n] = max(f[0][lx], f[1][lx])+max(f[0][ly], f[1][ly]);
        g[0][n] = 1ll*CAL(lx)*CAL(ly)%yzh;
        
        if (f[0][lx]+max(f[0][ly], f[1][ly]) >= f[0][ly]+max(f[0][lx], f[1][lx]))
            f[1][n] = f[0][lx]+max(f[0][ly], f[1][ly])+1,
            (g[1][n] += 1ll*g[0][lx]*CAL(ly)%yzh) %= yzh;
        if (f[0][lx]+max(f[0][ly], f[1][ly]) <= f[0][ly]+max(f[0][lx], f[1][lx]))
            f[1][n] = f[0][ly]+max(f[0][lx], f[1][lx])+1,
            (g[1][n] += 1ll*g[0][ly]*CAL(lx)%yzh) %= yzh;
    }
    int main() {
        scanf("%lld", &n);
        g[0][1] = 1, g[1][1] = 0;
        dp(n);
        if (f[0][n] == f[1][n]) printf("%lld %d
    ", f[0][n], (g[0][n]+g[1][n])%yzh);
        else if (f[0][n] > f[1][n]) printf("%lld %d
    ", f[0][n], g[0][n]);
        else printf("%lld %d
    ", f[1][n], g[1][n]);
        return 0;   
    }
  • 相关阅读:
    ID的插入
    开发语言的选择
    象数据库一样连接EXCEL
    前端,你真的了解JavaScript吗?
    开源软件与自由软件
    在codeigniter中使用Cache_Lite来缓存
    使用Codeigniter的SMTP类发Email
    JavaScript变量和数据类型
    JavaScript的隐式声明和变量声明提升的总结
    ASCII和UNICODE编码以及UTF8,你懂的?
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/11494865.html
Copyright © 2011-2022 走看看