|
发表于 2023-7-2 20:43:58
|
显示全部楼层
  这题很简单,直接开125个线段树,每个线段树维护一个区间里面所有数的乘积,然后遍历每个线段树的长度为4的区间,最后求最大值即可
答案: 70600674 (狗头保命)
- #include <bits/stdc++.h>
- #define lowbit(x) (x)&(-x)
- #define ls u<<1
- #define rs u<<1|1
- #define Mid(x,y) (x+y)>>1
- using namespace std;
- typedef long long LL;
- const int N = 25;
- int a[N][N], n = 20,cnt,b[N];
- struct Node
- {
- int l,r;
- LL v;
- }tr[125][4*N];
- void pushup(int u)
- {
- tr[cnt][u].v = tr[cnt][ls].v * tr[cnt][rs].v;
- }
- void build(int u,int l,int r)
- {
- tr[cnt][u] = {l,r};
- if(l==r)
- {
- tr[cnt][u].v = b[l];
- return;
- }
- int mid = Mid(l,r);
- build(ls,l,mid),build(rs,mid+1,r);
- pushup(u);
- }
- LL query(int u,int l,int r,int cnt)
- {
- if(tr[cnt][u].l>=l&&tr[cnt][u].r<=r) return tr[cnt][u].v;
- int mid = Mid(tr[cnt][u].l,tr[cnt][u].r);
- LL v = 1;
- if(l<=mid) v = query(ls,l,r,cnt);
- if(r>mid) v *= query(rs,l,r,cnt);
- return v;
- }
- int main()
- {
- for(int i=1;i<=n;i++)
- for(int j=1;j<=n;j++) cin>>a[i][j];
-
- for(int i=1;i<=n;i++)
- {
- memset(b,0,sizeof b);
- for(int j=1;j<=n;j++) b[j] = a[i][j]; //构建每一行
- build(1,1,n);
- cnt++;
- }
-
- for(int i=1;i<=n;i++)
- {
- memset(b,0,sizeof b);
- for(int j=1;j<=n;j++) b[j] = a[j][i]; //构建每一列
- build(1,1,n);
- cnt++;
- }
-
- //主对角线
- for(int i=1;i<=n;i++) //遍历第一行
- {
- memset(b,0,sizeof b);
- for(int x = 1,y = i,j = 1;x<=n&&y<=n;x++,y++,j++) b[j] = a[x][y];
- build(1,1,n);
- cnt++;
- }
- for(int i=1;i<=n;i++) //遍历第一列
- {
- memset(b,0,sizeof b);
- for(int x = i,y = 1,j = 1;x<=n&&y<=n;x++,y++,j++) b[j] = a[x][y];
- build(1,1,n);
- cnt++;
- }
-
- //次对角线
- for(int i=1;i<=n;i++) //遍历第一行
- {
- memset(b,0,sizeof b);
- for(int x = 1,y = i,j = 1;x<=n&&y>=1;x++,y--,j++) b[j] = a[x][y];
- build(1,1,n);
- cnt++;
- }
- for(int i=1;i<=n;i++) //遍历最后一列
- {
- memset(b,0,sizeof b);
- for(int x = i,y = n,j = 1;x<=n&&y>=1;x++,y--,j++) b[j] = a[x][y];
- build(1,1,n);
- cnt++;
- }
-
- LL ans = 0;
- for(int i=0;i<cnt;i++)
- {
- for(int j=1;j<=n-3;j++) ans = max(ans,query(1,j,j+3,i));
- }
- cout<<ans<<endl;
- return 0;
- }
复制代码 |
|