正题
题目大意
nnn个数,对于每个数找左边的一个数执行optoptopt操作使得答案最大,并且求有多少个数能够使得最大。
解题思路
我们设fi,jf_{i,j}fi,j表示下一个数的后888位为iii,当前数的前888位为jjj时的最大后888位的答案。然后每次用fi,bf_{i,b}fi,b统计完答案后更新fa,if_{a,i}fa,i即可。
时间复杂度O(nm)O(n\sqrt m)O(nm)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MS=1<<8;
int n,idx,f[MS][MS],g[MS][MS];
char op[8];
int main()
{//freopen("binary.in","r",stdin);//freopen("binary.out","w",stdout);scanf("%d%s%d",&n,op,&idx);for(int i=1;i<=n;i++){int x;scanf("%d",&x);int a=x&(MS-1),b=x>>8;if(i>1){int ans1=0,ans2=0; for(int j=0;j<MS;j++){int z;if(!g[a][j])continue;if(op[0]=='o')z=(j|b)<<8;else if(op[0]=='x')z=(j^b)<<8;else z=(j&b)<<8;if(f[a][j]+z>ans1)ans1=f[a][j]+z,ans2=g[a][j];else if(f[a][j]+z==ans1)ans2+=g[a][j];}printf("%d",ans1);if(idx==1)printf(" %d",ans2);putchar('\n');}for(int j=0;j<MS;j++){int z;if(op[0]=='o')z=j|a;else if(op[0]=='x')z=j^a;else z=j&a;if(z>f[j][b])f[j][b]=z,g[j][b]=1;else if(z==f[j][b])g[j][b]++;}}
}