• BZOJ5123 线段树的匹配(树形dp)


      线段树的任意一棵子树都相当于节点数与该子树相同的线段树。于是假装在树形dp即可,记忆化搜索实现,有效状态数是logn级别的。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<map>
    using namespace std;
    #define ll long long
    #define P 998244353
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    ll n;
    map<ll,ll> f[2],g[2];
    void solve(ll n)
    {
        if (g[0].find(n)!=g[0].end()) return;
        ll lson=n+1>>1,rson=n-lson;
        solve(lson),solve(rson);
        f[0][n]=max(f[0][lson],f[1][lson])+max(f[0][rson],f[1][rson]);
        f[1][n]=max(f[0][lson]+max(f[0][rson],f[1][rson]),f[0][rson]+max(f[0][lson],f[1][lson]))+1;
        ll x=f[0][lson]==f[1][lson]?g[0][lson]+g[1][lson]:(f[0][lson]>f[1][lson]?g[0][lson]:g[1][lson]);
        ll y=f[0][rson]==f[1][rson]?g[0][rson]+g[1][rson]:(f[0][rson]>f[1][rson]?g[0][rson]:g[1][rson]);
        g[0][n]=x*y%P;
        if (f[0][lson]+max(f[0][rson],f[1][rson])==f[0][rson]+max(f[0][lson],f[1][lson]))
        g[1][n]=(g[0][lson]*y+x*g[0][rson])%P;
        else if (f[0][lson]+max(f[0][rson],f[1][rson])>f[0][rson]+max(f[0][lson],f[1][lson])) g[1][n]=g[0][lson]*y%P;
        else g[1][n]=x*g[0][rson]%P;
        return;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj5123.in","r",stdin);
        freopen("bzoj5123.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        cin>>n;f[0][1]=0,f[1][1]=-n,g[0][1]=1,g[1][1]=0;
        solve(n);
        if (f[0][n]==f[1][n]) cout<<f[0][n]<<' '<<(g[0][n]+g[1][n])%P;
        else if (f[0][n]>f[1][n]) cout<<f[0][n]<<' '<<g[0][n];
        else cout<<f[1][n]<<' '<<g[1][n];
        return 0;
    }
  • 相关阅读:
    视频后期制作Premiere Pro 2022
    【Mac win】C和C ++ IDE智能代码编辑器CLion 2022
    Linux获取系统cpu%和用户cpu%使用率
    记录jenkins因为缓存空间不足挂掉问题
    Python取出数组中重复次数最多的数
    docker实现format格式化输出内容
    Python统计list中每个元素出现的个数
    Linux dig命令
    Python 获取内存信息
    awk 取得文件里最后一行
  • 原文地址:https://www.cnblogs.com/Gloid/p/10089009.html
Copyright © 2020-2023  润新知