CF-579D."Or" Game(或运算)

传送门


解题思路

看到题的第一眼,直觉告诉我要把所有的数乘在最大的数身上,但举了一个反例:

2 1 2

2 3

这样乘在2身上明显答案更优。

所以并不能确定应该乘在谁的身上,但是可以保证一定是把所有数都乘在一个数身上。

那么怎么优化O(n^2)的时间复杂度呢?

我们可以预处理一个数组存所有数字二进制拆分后的每一位有几个数字有,这样在枚举被乘的数的时候,就可以O(64)求出答案,与最优解比较。

总时间复杂度为O(64n)。

但比较奇特的是用c++11WA在第九个点,用c++14AC了。

而且第九个点在本机跑是正确的。//大雾

AC代码

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<iomanip>
 5 #include<cmath>
 6 using namespace std;
 7 const int maxn=200005;
 8 int n,a[maxn],num[65];
 9 long long k,x,ans; 
10 int main(){
11     cin>>n>>k>>x;
12     long long xx=pow(x,k);
13     for(int i=1;i<=n;i++){
14         scanf("%d",&a[i]);
15         int x=a[i],cnt=0;
16         while(x>0){
17             cnt++;
18             if(x&1) num[cnt]++;
19             x>>=1;
20         }
21     }
22     for(int i=1;i<=n;i++){
23         long long x=a[i],cnt=0,res=0;
24         while(x>0){
25             cnt++;
26             if(x&1) num[cnt]--;
27             x>>=1;
28         }
29         cnt=1;
30         for(int j=1;j<=63;j++){
31             if(num[j]) res+=cnt;
32             cnt<<=1;
33         }
34         ans=max(ans,res|(a[i]*xx));
35         x=a[i];
36         cnt=0;
37         while(x>0){
38             cnt++;
39             if(x&1) num[cnt]++;
40             x>>=1;
41         }
42     }
43     cout<<ans;
44     return 0;
45 }

 

posted @ 2021-02-20 10:45  尹昱钦  阅读(95)  评论(0编辑  收藏  举报