Description
![](https://i-blog.csdnimg.cn/blog_migrate/f4d23e8618d0c2f28a2390e5b9661963.png)
Input
![](https://i-blog.csdnimg.cn/blog_migrate/c211cd22e778e2749f4faeace4d2ca7d.png)
Output
![](https://i-blog.csdnimg.cn/blog_migrate/8dd398b70483e695ee502effaf53bf8f.png)
Sample Input
5 and 1
3 5 2 7 1
Sample Output
1 1
2 1
5 1
1 3
Data Constraint
![](https://i-blog.csdnimg.cn/blog_migrate/8a3e187a5bd2a530e145b56873465146.png)
题解
- 对于普通的暴力,因为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 }