You are given an array 𝑎 of 𝑛 integers.c++
You need to find the maximum value of 𝑎𝑖|(𝑎𝑗&𝑎𝑘) over all triplets (𝑖,𝑗,𝑘) such that 𝑖<𝑗<𝑘.express
Here & denotes the bitwise AND operation, and | denotes the bitwise OR operation.spa
The first line of input contains the integer 𝑛 (3≤𝑛≤106), the size of the array 𝑎.code
Next line contains 𝑛 space separated integers 𝑎1, 𝑎2, ..., 𝑎𝑛 (0≤𝑎𝑖≤2⋅106), representing the elements of the array 𝑎.ip
Output a single integer, the maximum value of the expression given in the statement.element
3
2 4 6input
6it
4
2 8 4 7io
12for循環
In the first example, the only possible triplet is (1,2,3). Hence, the answer is 2|(4&6)=6.
In the second example, there are 4 possible triplets:
(1,2,3), value of which is 2|(8&4)=2.
(1,2,4), value of which is 2|(8&7)=2.
(1,3,4), value of which is 2|(4&7)=6.
(2,3,4), value of which is 8|(4&7)=12.
The maximum value hence is 12.
給你n個數,而後讓你找到三個不一樣的ijk,使得a[i]|(a[j]&a[k])最大
比較顯然的作法是枚舉a[i],而後從高位到地位看最大的(a[j]&a[k])是多少。
(a[j]&a[k])這個東西咱們單獨維護,枚舉a[j]的每一位,舉個例子好比a[j]是10001,那麼咱們讓cnt[10000],cnt[10001],cnt[00001]都加1;好比00101,咱們讓cnt[00100]和cnt[00001],cnt[00101]都加上1。
而後咱們從高位到地位for循環貪心找到cnt[x]>2的最大的便可。
這個枚舉能夠用sosdp來作;也能夠比較牛逼的操做每一位來枚舉,看法法1。
#include<bits/stdc++.h> using namespace std; const int N=4000005; int n,cnt[N],ans,a[N]; void insert(int x,int y){ if (cnt[x|y]==2)return; if (x==0){ cnt[y]++; return; } insert(x&x-1,y|x&-x); insert(x&x-1,y); // x&x-1是取消最小的一位,x&-x是取最小的一位 } int main() { scanf("%d",&n); for (int i=1;i<=n;i++)scanf("%d",&a[i]); for (int i=n;i>=1;i--){ if (i+2<=n){ int now=0; for (int j=20;j>=0;j--) if (!((1<<j)&a[i])&&cnt[now|1<<j]==2)now|=1<<j; ans=max(ans,now|a[i]); } insert(a[i],0); } printf("%d\n",ans); return 0; } /* sos dp #include <bits/stdc++.h> using namespace std; const int maxn = 1<<21; int dp[maxn][21],a[maxn],n; void sosdp(int num,int k){ if(k>20)return; if(dp[num][k]>1)return; dp[num][k]++; sosdp(num,k+1); if(num>>k&1){ sosdp(num^(1<<k),k); } } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } int ans = 0; for(int i=n;i>=1;i--){ int res = 0, t = 0; for(int j=20;j>=0;j--){ if(a[i]>>j&1){ res|=1<<j; }else if(dp[t|(1<<j)][20]>1){ res|=1<<j; t|=1<<j; } } sosdp(a[i],0); if(i<=n-2){ ans=max(ans,res); } } cout<<ans<<endl; } */