D. Walk on Matrix
D 他的错误dp是因为&过程中的最大值不一定能使后面的&操作最大
要使最优解与他输出的差值为k,感觉两个值分别等 k和0是比较好构造吧,所以我的目的是使最优解为k,而dp输出0,假设点[n,m]位置为k,为方便构造减少分支情况就把所有情况都从一个方向来,就令[n-1,m]为0,这个方向一定为0。
接下来就是使 dp[n][m-1]&k 等0,而[n,m-1]可以得到的较小的值&k等k,什么值&k等0呢,k按位取反(令他为m)。
然后看一下m的范围是3e5是不是一定比1e5范围的k大,3e5以内的数二进制最多有19位,而1e5以内最多有17位,所以k的18位上一定是0,那么m的18位就一定是1了,所以m一定大于k 。
所以就可构造[n-1,m-1]为m,[n,m-2]为k,令s=2^18-1(二进制下各位都是1,小于3e5的最大值,&任何数的结果都等原数),其他位所有数都为s,这样两行三列足矣,所以构造的矩阵就是 s m 0
k s k
转自 帅佬博客
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
typedef long long ll;
int t,n,k,m,s;
int a[N],c[N];
char s[N];
int main()
{
cin>>k;
for(int i=0;i<20&&(m+(1<<i)<3e5);i++)
{
s+=(1<<i);
if((k&(1<<i))==0&&m+(1<<i)<3e5)
m+=(1<<i);
}
cout<<2<<' '<<3<<endl;
cout<<s<<' '<<k<<' '<<0<<endl;
cout<<m<<' '<<s<<' '<<k;
return 0;
}