题目
题意: 给定三维平面上点(i,j,k)对应的权值,维护三维前缀和。
思路: 容斥原理。
s = 1 - 2 + 3
query: s2 - (1 - 2 + 3)
时间复杂度: O(input + query)
代码:
// Problem: 星球大战
// Contest: QDUOJ
// URL: https://qduoj.com/problem/22Spring7
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<complex>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<unordered_map>
#include<list>
#include<set>
#include<queue>
#include<stack>
#define OldTomato ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define p_ priority_queue
// round() 四舍五入 ceil() 向上取整 floor() 向下取整
// lower_bound(a.begin(),a.end(),tmp,greater<ll>()) 第一个小于等于的
// #define int long long //QAQ
using namespace std;
typedef complex<double> CP;
typedef pair<int,int> PII;
typedef long long ll;
// typedef __int128 it;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll inf = 1e18;
const int N = 102;
const int M = 1e6+10;
const int mod = 1000000007;
const double eps = 1e-6;
inline int lowbit(int x){ return x&(-x);}
template<typename T>void write(T x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
#define int long long
int n,m,k,t,T;
int a[N][N][N];
int s[N][N][N];
int query(int x1,int y1,int z1,int x2,int y2,int z2)
{
return s[x2][y2][z2] - s[x1-1][y2][z2] - s[x2][y1-1][z2] - s[x2][y2][z1-1] + s[x1-1][y1-1][z2] + s[x1-1][y2][z1-1] + s[x2][y1-1][z1-1] - s[x1-1][y1-1][z1-1];
}
void solve()
{
read(t); read(n); read(m); int q;
for(int k=1;k<=t;++k)
{
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
{
read(a[i][j][k]);
s[i][j][k] = (a[i][j][k] + s[i-1][j][k] + s[i][j-1][k] + s[i][j][k-1] - s[i-1][j-1][k] - s[i-1][j][k-1] - s[i][j-1][k-1] + s[i-1][j-1][k-1]) % mod;
s[i][j][k] = (s[i][j][k] + 3ll*mod) % mod;
//-1+2-3
}
}
}
read(q);
for(int i=1;i<=q;++i)
{
int x1,y1,z1,x2,y2,z2;
read(z1),read(x1),read(y1),read(z2),read(x2),read(y2);
int ans = query(x1,y1,z1,x2,y2,z2);
ans = (ans + 3ll*mod) % mod;
printf("case %lld: %lld\n",i,ans);
}
}
signed main(void)
{
T = 1;
// OldTomato; cin>>T;
// read(T);
while(T--)
{
solve();
}
return 0;
}