题解
- 对于普通的暴力,因为ai小于等于2^16,所以暴力做可以做到加入O(1),而查询O(2^16),显然是不可以的
- 考虑把两个操作平衡一下,f[x][y]表示前半段为x,后半段的数与y运算的最大值,g[x][y]记录个数
- 我们在加入一个数时,我们枚举j,设该数前8位为a,后8位为b来更新f[a][j]
- 查询时,设该数前8位为a,后8位为b,我们可以枚举i用f[i][b]|((i~a)<<8)更新答案即可
- 复杂度为O(2^8*n)
代码
1 #include <cstdio>
2 #include <iostream>
3 #include <cstring>
4 using namespace std;
5 const int N=1e5+10,M=256;
6 int n,type,sum,ans,a[N],f[M][M],g[M][M];
7 char s[10];
8 int calc(int x,int y) { return s[0]=='o'?x|y:(s[0]=='a'?x&y:x^y); }
9 int main()
10 {
11 freopen("binary.in","r",stdin),freopen("binary.out","w",stdout);
12 scanf("%d%s%d",&n,&s,&type);
13 for (int i=1;i<=n;i++) scanf("%d",&a[i]);
14 for (int i=1;i<=n;i++)
15 {
16 int k=a[i]&255;
17 if (i>1)
18 {
19 sum=ans=0;
20 for (int j=0;j<=255;j++)
21 if (g[j][k])
22 {
23 if ((f[j][k]|calc(j,a[i]>>8)<<8)==ans) sum+=g[j][k];
24 else if ((f[j][k]|calc(j,a[i]>>8)<<8)>ans) ans=f[j][k]|calc(j,a[i]>>8)<<8,sum=g[j][k];
25 }
26 if (type==1) printf("%d %d\n",ans,sum); else printf("%d\n",ans);
27 }
28 for (int j=0;j<=255;j++) if (f[a[i]>>8][j]==calc(j,k)) g[a[i]>>8][j]++; else if (f[a[i]>>8][j]<calc(j,k)) f[a[i]>>8][j]=calc(j,k),g[a[i]>>8][j]=1;
29 }
30 }