• [CF GYM102956D] Bank Security Unification


    前言

    性质结论题。

    题目

    CF

    题目大意:

    \(n\) 个数,选出一些数使得相邻两个数的与的算术和最大,求这个最大值。(不能改变相对顺序)

    \(1\le n\le 10^6;0\le a_i\le 10^{12}.\)

    讲解

    首先我们不难得到一个 \(O(n^2)\) 的DP,然后考虑如何优化。

    不难发现如果依次存在三个数 \(a_i,a_j,a_k\) 使得 \(a_i\&a_k\) 的最高位在 \(a_j\) 处也为 \(1\),那么我们一定不会丢下 \(a_j\) 而只选 \(a_i,a_k\)

    所以我们可以考虑枚举这一位,之前选之前最近的一个存在这一位的数作为前置转移点即可。

    时间复杂度 \(O(n\log_2a)\)

    代码

    //12252024832524
    #include <bits/stdc++.h>
    #define TT template<typename T>
    using namespace std; 
    
    typedef long long LL;
    const int MAXN = 1000005;
    int n,pre[45];
    LL a[MAXN],dp[MAXN],ans;
    
    LL Read()
    {
    	LL x = 0,f = 1;char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read();
    	for(int i = 1;i <= n;++ i) a[i] = Read();
    	for(int i = 1;i <= n;++ i)
    	{
    		for(int j = 0;j <= 40;++ j)
    			if(a[i] >> j & 1)
    			{
    				dp[i] = Max(dp[i],dp[pre[j]]+(a[i]&a[pre[j]]));
    				pre[j] = i;
    				ans = Max(ans,dp[i]);
    			}
    		dp[i] = Max(dp[i],ans);//attention!
    	}
    	Put(ans,'\n');
    	return 0;
    }
    
  • 相关阅读:
    [GEF]实现模板功能
    一篇WTP文章
    写代码的代码:JET
    投票选择eclipse.org的新界面
    在SWT里显示AWT对象
    Plugin.xml > Manifest.mf
    关于本体编程的实现
    一个用OWLS组装Web服务的例子
    感受Ruby on Rails
    通过OCP考试
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/15867177.html
Copyright © 2020-2023  润新知