[ABC366D] Cuboid Sum Query 题解
题意翻译:
给予一个 \(N \times N \times N\) 的三维矩阵,有 \(Q\) 次询问,对于每次询问,给与四个数,分别为 \(L_1,R_1,L_2,R_2,L_3,R_3\) 求在三维矩阵中 \(a[L_1][L_2][L_3]\) 到 \(a[R_1][R_2][R_3]\) 的区间和。
三维前缀和板子题,虽然本蒟蒻也是现学的,但这并不影响做题。走着。
首先是三维前缀和的初始化,我们可以一维一维处理前缀和,三重循环即可:
int a[maxn][maxn][maxn]; //前缀和数组
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
a[i][j][k]+=a[i-1][j][k];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
a[i][j][k]+=a[i][j-1][k];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
a[i][j][k]+=a[i][j][k-1];
前缀和处理完了,问题变成如何求区间和。
运用容斥原理,可以推出这样一个式子:
\[S=a[R_1][R_2][R_3]-a[L_1-1][R_2][R_3]-a[R_1][L_2-1][R_3]-a[R_1][R_2][L_3-1]+a[L_1-1][L_2-1][R_3]+a[L_1-1][R_2][L_3-1]+a[R_1][L_2-1][R_3-1]-a[L_1-1][L_2-1][L_3-1] \]这便是需要输出的答案。
此题结束。
AC code:
#include <bits/stdc++.h>
#define seq(q, w, e) for (int q = w; q <= e; q++)
#define ll long long
using namespace std;
const int maxn = 110;
int n,t;
int a[maxn][maxn][maxn];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
seq(i,1,n){
seq(j,1,n){
seq(k,1,n){
cin>>a[i][j][k];
}
}
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
for(int k = 1; k <= n; k++)
a[i][j][k] += a[i - 1][j][k];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
for(int k = 1; k <= n; k++)
a[i][j][k] += a[i][j - 1][k];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
for(int k = 1; k <= n; k++)
a[i][j][k] += a[i][j][k - 1];
cin>>t;
while(t--){
int b1,b2,b3,e1,e2,e3;
cin>>b1>>e1>>b2>>e2>>b3>>e3;
cout<<a[e1][e2][e3]-a[b1-1][e2][e3]-a[e1][b2-1][e3]-a[e1][e2][b3-1]+a[b1-1][b2-1][e3]+
a[b1-1][e2][b3-1]+a[e1][b2-1][b3-1]-a[b1-1][b2-1][b3-1]<<endl;
}
return 0;
}
标签:前缀,seq,Cuboid,题解,Sum,int,maxn,Query
From: https://www.cnblogs.com/adsd45666/p/18354338