二进制的世界
Posted StaroForgin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二进制的世界相关的知识,希望对你有一定的参考价值。
二进制的世界
题解
有趣的做法,准确说是我太菜了,
S
Y
D
e
v
i
l
SYDevil
SYDevil大佬秒切了
我们可以考虑对于每个数二进制分段。
由于
a
i
<
2
16
a_{i}< 2^{16}
ai<216,所以我们可以记录下
d
p
i
,
j
dp_{i,j}
dpi,j表示前
8
8
8位为
i
i
i的数的后八位与
j
j
j进行操作可以得到的后八位最大值。
由于这些数前
8
8
8位是一样的,所以当这些数与某个数进行操作后,前
8
8
8位都是一样的,它们不同的地方在后
8
8
8位,而这后
8
8
8位有是与另一个数的后
8
8
8位进行操作的,所以我们只需要固定另外一个数的后
8
8
8位,就可以知道所有前
8
8
8位为
i
i
i的数与这个数进行操作的最大值。
而对于每个数,它自身的后
8
8
8位是固定的,我们只需要枚举它的前
8
8
8位与哪个数进行操作。
同理,当它加入
d
p
dp
dp答案时,我们也只需要枚举它的后
8
8
8位与哪个数进行操作,加入
d
p
dp
dp状态。
很明显,我们对于每个数会进行 2 8 2^8 28次操作,所以时间复杂度是 O ( n a ) O\\left(n\\sqrt{a}\\right) O(na)的。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
const LL INF=0x3f3f3f3f;
const int mo=1e9+7;
const int inv2=499122177;
const int jzm=2333;
const int lim=1e9;
const int n1=150;
const int zero=10000;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
const double eps=1e-5;
typedef pair<LL,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
_T f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
LL gcd(LL a,LL b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
void Add(int &x,int y,int p){x=add(x,y,p);}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1LL)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1LL;}return t;}
const int M=MAXN/n1+5;
int n,typ,a[MAXN],dp[260][260],cnt[260][260],op;
char opt[10];
inline int work(int x,int y){return (op==1)?(x&y):((op==2)?(x|y):(x^y));}
signed main(){
scanf("%d %s",&n,opt+1);
if(opt[1]=='a')op=1;else if(opt[1]=='o')op=2;else op=3;
for(int i=1;i<=n;i++)read(a[i]);
for(int i=1;i<=n;i++){
int maxx=0,res=0,S1=a[i]>>8,S2=a[i]&((1<<8)-1);
if(i>1)for(int j=0;j<(1<<8);j++)if(cnt[j][S2]){
int tmp=(work(S1,j)<<8)|dp[j][S2];
if(tmp>maxx)maxx=tmp,res=0;
if(tmp==maxx)res+=cnt[j][S2];
}
for(int j=0;j<(1<<8);j++){
int tmp=work(S2,j);
if(tmp>dp[S1][j])dp[S1][j]=tmp,cnt[S1][j]=0;
if(dp[S1][j]==tmp)cnt[S1][j]++;
}
if(i>1)printf("%d %d\\n",maxx,res);
}
return 0;
}
谢谢!!!
以上是关于二进制的世界的主要内容,如果未能解决你的问题,请参考以下文章
android.view.InflateException:二进制 XML 文件第 15 行:二进制 XML 文件第 19 行:膨胀类片段时出错
当我切换到包含片段的活动时应用程序崩溃(二进制 XML 文件第 10 行:二进制 XML 文件第 10 行:膨胀类片段时出错)