• Solution -「LOCAL」二进制的世界


    (mathcal{Description})

      OurOJ.

      给定序列 ({a_n}) 和一个二元运算 (operatorname{op}in{operatorname{and},operatorname{or},operatorname{xor}}),对于 (iin[2,n]),求出 (max_{jin[1,i)}{a_ioperatorname{op} a_j}) 以及 (|argmax_{jin[1,i)}{a_ioperatorname{op} a_j}|)

      (nle10^5)(a_i<2^{16})

    (mathcal{Solution})

      也许算是 Meet in Middle?从左到右在线更新可用的 (a_j) 信息并求出对于当前 (i) 的答案,维护一个 (f(u,v)),表示选取的 (a_j) 的高八位是 (u)(a_i) 的低八位是 (v) 时,低八位能得到的最大值以及方案数。那么更新时,用当前 (a_j) 的低八位更新所有 (f(u,i));查询时枚举高八位选择的值 (i),并用 (f(i,v)) 更新答案。最终复杂度为 (mathcal O(nsqrt A))

      确实是比较巧妙的复杂度平衡,也是一个实用的 trick√

    (mathcal{Code})

    /*~Rainybunny~*/
    
    #include <bits/stdc++.h>
    
    #define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
    #define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
    
    typedef std::pair<int, int> PII;
    #define fi first
    #define se second
    
    const int MAXN = 1e5, MAXSV = 1 << 8;
    int n, a[MAXN + 5];
    char op[5];
    PII f[MAXSV][MAXSV];
    
    inline void update( const int x, const auto& opt ) {
        int h = x >> 8, l = x ^ h << 8;
        rep ( i, 0, MAXSV - 1 ) {
            int v = opt( i, l );
            if ( f[h][i].fi < v ) f[h][i] = { v, 1 };
            else if ( f[h][i].fi == v ) ++f[h][i].se;
        }
    }
    
    inline PII query( const int x, const auto& opt ) {
        int l = x & ( ( 1 << 8 ) - 1 );
        PII ret( 0, 0 );
        rep ( h, 0, MAXSV - 1 ) if ( f[h][l].se ) {
            int cur = opt( h, x >> 8 ) << 8 | f[h][l].fi;
            if ( ret.fi < cur ) ret = { cur, f[h][l].se };
            else if ( ret.fi == cur ) ret.se += f[h][l].se;
        }
        return ret;
    }
    
    inline void solve( const auto& opt ) {
        update( a[1], opt );
        rep ( i, 2, n ) {
            PII ans( query( a[i], opt ) );
            printf( "%d %d
    ", ans.fi, ans.se ), update( a[i], opt );
        }
    }
    
    int main() {
        scanf( "%d %s", &n, op );
        rep ( i, 1, n ) scanf( "%d", &a[i] );
        if ( op[0] == 'x' ) {
            solve( []( const int u, const int v ) { return u ^ v; } );
        } else if ( op[0] == 'a' ) {
            solve( []( const int u, const int v ) { return u & v; } );
        } else {
            solve( []( const int u, const int v ) { return u | v; } );
        }
        return 0;
    }
    
    
  • 相关阅读:
    StrCopy、StrCat、StrPas
    WinAPI: FlashWindow 闪烁窗口
    WinAPI: SetVolumeLabel 设置磁盘卷标
    WinAPI: GetActiveWindow 获取当前活动窗口的句柄
    WinAPI: SetCurrentDirectory、GetCurrentDirectory 设置与获取当前目录
    WinAPI: CreateDirectoryEx 根据模版建立文件夹
    WinAPI: CreateDirectory 建立文件夹
    WinAPI: RemoveDirectory 删除空目录
    WinAPI: GetLogicalDriveStrings 获取系统中存在的逻辑驱动器字符串
    filer.js: 一个 Unix 命令风格的 HTML 5 FileSystem API 封装 V2EX
  • 原文地址:https://www.cnblogs.com/rainybunny/p/15293117.html
Copyright © 2020-2023  润新知