时间限制: 2 Sec 内存限制: 128 MB
题目描述
经过数天的艰苦跋涉, R a i n y 7 Rainy7 Rainy7 终于进入了魔法王国。由于 R a i n y 7 Rainy7 Rainy7 是大魔法师,所以她受到了国王 3 e d c 2 w s x 1 q a z 3edc2wsx1qaz 3edc2wsx1qaz 的热情款待。
R a i n y 7 Rainy7 Rainy7 享用完国宴后,国王向她道出了魔法王国的困难:王国正遭受着魔兽的袭击。王国中的所有人都无法击败魔兽,所以国王恳请大魔法师 R a i n y 7 Rainy7 Rainy7 帮助王国与魔兽战斗。
R a i n y 7 Rainy7 Rainy7 爽快地答应了。国王欣喜若狂,并立即邀请 R a i n y 7 Rainy7 Rainy7 到魔法世界最大的魔法阵中汲取魔法,以做好战斗准备。
这个魔法阵是一个 n n n 行 m m m 列的矩阵,矩阵中每个格子都有一个非负整数的魔法值,第 i i i 行第 j j j 列的格子的魔法值为 a i , j a_{i,j} ai,j。
R a i n y 7 Rainy7 Rainy7 要从第 1 1 1 行第 1 1 1 列的格子走到第 n n n 行第 m m m 列的格子。如果 R a i n y 7 Rainy7 Rainy7当前在第i行第j列的格子上,则她下一步可以走到第 i + 1 i+1 i+1 行第j列的格子或第 i i i 行第 j + 1 j+1 j+1 列的格子上(如果那个格子存在的话),直到她走到第 n n n 行第 m m m 列的格子为止。
R a i n y 7 Rainy7 Rainy7 只能按这样的方式走一次。走完后, R a i n y 7 Rainy7 Rainy7 汲取到的魔法值是她走过的所有格子的魔法值的与和,即把她走过的所有格子的魔法值全部按位与起来的结果。
R a i n y 7 Rainy7 Rainy7 想知道她最多能汲取到多少魔法值。 R a i n y 7 Rainy7 Rainy7 只用了 11451 4 − 1919810 114514^{-1919810} 114514−1919810s就算出了答案,在她开始汲取魔法之前,她也想让你解决这个问题。
顷刻间,魔法汲取完毕了, R a i n y 7 Rainy7 Rainy7 便坚定地向战场走去……
输入
第一行两个整数 n , m n,m n,m,分别表示魔法阵的行数和列数。
接下来 n n n 行,每行包含 m m m 个整数,其中第 i i i 的第 j j j 个数表示 a i , j a_{i,j} ai,j。
输出
输出一行一个整数,表示 R a i n y 7 Rainy7 Rainy7 能汲取到的魔法值的最大值。
样例输入
【样例1】
3 4
3 7 7 7
6 3 8 4
1 3 3 7
【样例2】
10 10
2047 2047 1535 2043 863 1983 2046 2015 2047 2047
1903 1535 1982 2015 2047 1531 1791 2015 2025 2045
767 927 2023 2039 2015 1918 2042 2039 935 2047
2022 2045 1499 991 2046 2047 2047 959 1023 2047
2038 1999 2046 1919 1519 2015 1007 2047 2047 1023
2047 991 1983 2047 1919 1655 1791 2013 1535 2047
2047 2047 1974 1535 2047 2031 1847 1535 2047 2045
1023 1023 2047 2047 1919 2011 1983 1791 1979 2023
2047 2047 2047 2045 1503 511 1023 2004 2039 2047
895 1525 2031 1911 2039 1967 1852 1023 1983 2047
样例输出
【样例1】
3
【样例2】
1284
提示
样例 1 1 1 解释:
我们用 ( i , j ) (i,j) (i,j) 表示魔法阵第 i i i 行第 j j j 列的格子。
R a i n y 7 Rainy7 Rainy7 走过的路径为: ( 1 , 1 ) − > ( 1 , 2 ) − > ( 2 , 2 ) − > ( 3 , 2 ) − > ( 3 , 3 ) − > ( 3 , 4 ) (1,1)->(1,2)->(2,2)->(3,2)->(3,3)->(3,4) (1,1)−>(1,2)−>(2,2)−>(3,2)−>(3,3)−>(3,4),汲取到的魔法值为 3 a n d 7 a n d 3 a n d 4 a n d 3 a n d 7 = 3 3 \quad and \quad7 \quad and \quad 3 \quad and\quad 4\quad and\quad 3\quad and\quad 7 = 3 3and7and3and4and3and7=3。
样例 2 2 2 解释:
R a i n y 7 Rainy7 Rainy7 走过的一种最佳路径为:
( 1 , 1 ) − > ( 1 , 2 ) − > ( 1 , 3 ) − > ( 2 , 3 ) − > ( 2 , 4 ) − > ( 2.5 ) − > ( 3 , 5 ) − > ( 4 , 5 ) − > ( 5 , 5 ) − > ( 6 , 5 ) − > ( 7 , 5 ) − > ( 7 , 6 ) − > ( 7 , 7 ) − > ( 7 , 8 ) − > ( 7 , 9 ) − > ( 7 , 10 ) − > ( 8 , 10 ) − > ( 9 , 10 ) − > ( 10.10 ) (1,1)->(1,2)->(1,3)->(2,3)->(2,4)->(2.5)->(3,5)->(4,5)->(5,5)->(6,5)->(7,5)->(7,6)->(7,7)->(7,8)->(7,9)->(7,10)->(8,10)->(9,10)->(10.10) (1,1)−>(1,2)−>(1,3)−>(2,3)−>(2,4)−>(2.5)−>(3,5)−>(4,5)−>(5,5)−>(6,5)−>(7,5)−>(7,6)−>(7,7)−>(7,8)−>(7,9)−>(7,10)−>(8,10)−>(9,10)−>(10.10)。
对于全部数据, 1 ≤ n , m ≤ 2 × 1 0 3 , 0 ≤ a i , j ≤ 2 31 − 1 1≤n,m≤2×10^3,0≤a_{i,j}≤2^{31}-1 1≤n,m≤2×103,0≤ai,j≤231−1。
枚举每一位 d p dp dp,记录路径
/*** Amber ***/
#pragma GCC optimize(3,"Ofast","inline")
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
typedef long long ll;
template <typename T>
inline void read(T &x) {
x = 0;
static int p;
p = 1;
static char c;
c = getchar();
while (!isdigit(c)) {
if (c == '-')p = -1;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c - 48);
c = getchar();
}
x *= p;
}
template <typename T>
inline void print(T x) {
if (x<0) {
x = -x;
putchar('-');
}
static int cnt;
static int a[50];
cnt = 0;
do {
a[++cnt] = x % 10;
x /= 10;
} while (x);
for (int i = cnt; i >= 1; i--)putchar(a[i] + '0');
puts("");
}
const double Pi=acos(-1);
const double eps=1e-6;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const ll Inf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 2e3+10;
ll a[maxn][maxn],f[maxn][maxn],ans;
int n,m;
bool vis[maxn][maxn];
inline void work() {
read(n);
read(m);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
read(a[i][j]);
vis[i][j] = 1;
}
}
for (int k = 32; k >= 0; k--) {
ll tmp = 1ll << k;
if ((tmp & a[1][1]) == 0) continue;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
f[i][j] = 0;
}
}
f[1][1] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (i == 1 && j == 1) continue;
if (a[i][j] & tmp) f[i][j] = (f[i - 1][j] && vis[i - 1][j]) || (f[i][j - 1] && vis[i][j - 1]);
}
}
if (!f[n][m]) continue;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (!f[i][j]) vis[i][j] = 0;
}
}
ans += tmp;
}
print(ans);
}
int main() {
//freopen("1.txt","r",stdin);
int T = 1;
//read(T);
while (T--) {
work();
}
return 0;
}