ABC291G 题解
ABC291G OR Sum
题意:有两个长度为
题解:发现 or 操作有点点困难,那么我们就把两个序列取反,然后求 and 的最小值。
尝试形式化枚举每个移动数量的过程,比如枚举一个移位
这种位数特别少的题,就先枚举二进制位
然后就是两个 0/1 序列合并操作,我们需要求出一个答案数组
我们可以把
这个形式还不是我们熟悉的形式,我们应该熟悉的形式是
怎么办呢?拿
左边式子
右边下标为负数的很不好看,因为我们需要存储
令
发现就是多项式的形式,直接卷积即可。
时间复杂度
#include<bits/stdc++.h>
#include<atcoder/all>
using namespace std;
typedef int I;
I main(){I n;
scanf("%d",&n);
vector<I>a(n),b(n),c(n),d(n<<1),e,f(n);
for(I i=0;i<n;++i)scanf("%d",&a[i]);
for(I i=0;i<n;++i)scanf("%d",&b[i]);
for(I k=0;k<5;++k){
for(I i=0;i<n;++i)d[i]=(~b[i]>>k)&1,d[i+n]=d[i],c[n-1-i]=(~a[i]>>k)&1;
e=atcoder::convolution(c,d);
for(I i=0;i<n;++i)f[i]+=(n-e[i+n-1])<<k;}
printf("%d\n",*max_element(f.begin(),f.end()));
return 0;
}