2 条题解

  • 2
    @ 2025-6-2 16:48:42

    考虑或运算的性质,发现数值大的数和数值小的数得到的结果会更优,故将所有次数都用在最大值上即可。 对于c++选手,要开long long

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int const N=1e5+10;
    int a[N];
    signed main()
    {
    	int n,k,x;
    	cin>>n>>k>>x;
    	int max=0,pos=0;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    		if(max<a[i]) max=a[i],pos=i;
    	}
    	while(k--) a[pos]*=x;
    	int ans=a[1];
    	for(int i=2;i<=n;i++) ans|=a[i];
    	cout<<ans;
    	return 0;
    }
    
    
    • 0
      @ 2025-6-6 20:08:46

      由于 2x2 \le x,所以一个数乘上 xx 后必定会向右移至少一位。因此这 kk 次操作肯定是做在同一个数上更优。则我们只需要枚举这个操作的数,然后做前缀或和后缀或来求所有数的或即可。

      import sys
      
      def main():
          data = sys.stdin.read().split()
          n = int(data[0])
          k = int(data[1])
          x = int(data[2])
          a = list(map(int, data[3:3+n]))
      
          # 计算x的k次方
          xk = 1
          for _ in range(k):
          xk *= x
      
          # 前缀或数组,pre[i]表示前i个元素的或(a[0]到a[i-1])
          pre = [0] * (n + 1)
          for i in range(1, n + 1):
          pre[i] = pre[i - 1] | a[i - 1]
      
          # 后缀或数组,bac[i]表示从a[i]到末尾的或
          bac = [0] * (n + 2)  # 多分配一个空间避免越界
          for i in range(n - 1, -1, -1):
          bac[i] = bac[i + 1] | a[i]
      
          ans = 0
          for i in range(n):
              # 修改当前元素:乘以x^k
              modified = a[i] * xk
              # 计算整个数组的或:前缀或 | 修改后的元素 | 后缀或
              current = pre[i] | modified | bac[i + 1]
              if current > ans:
              ans = current
      
          print(ans)
      
      if __name__ == '__main__':
          main()
      
      • 1

      信息

      ID
      982
      时间
      1000ms
      内存
      128MiB
      难度
      1
      标签
      (无)
      递交数
      144
      已通过
      19
      上传者