#include<bits/stdc++.h>
using namespace std;
#define int long long
#define INT_MAX LONG_LONG_MAX
#define INT_MIN LONG_LONG_MIN
int a[10000005],n,m,c,s,cf[10000005];
struct node {
int xt,xp,yt,yp,zt,zp,h;
} q[10000005];
int to_wei(int i,int j,int k) { //to_wei(i,j,k)表示将第i行第j列第k层转换成一维坐标
return ((k-1)*n+i-1)*m+j;
}
int check(int mid) {
memset(cf,0,sizeof(cf));
for(int i = 1; i<=mid; i++) {
cf[to_wei(q[i].xt,q[i].yt,q[i].zt)] = cf[to_wei(q[i].xt,q[i].yt,q[i].zt)]+q[i].h;
cf[to_wei(q[i].xt,q[i].yp+1,q[i].zt)] = cf[to_wei(q[i].xt,q[i].yp+1,q[i].zt)]-q[i].h;
cf[to_wei(q[i].xp+1,q[i].yt,q[i].zt)] = cf[to_wei(q[i].xp+1,q[i].yt,q[i].zt)]-q[i].h;
cf[to_wei(q[i].xp+1,q[i].yp+1,q[i].zt)] = cf[to_wei(q[i].xp+1,q[i].yp+1,q[i].zt)]+q[i].h;
cf[to_wei(q[i].xt,q[i].yt,q[i].zp+1)] = cf[to_wei(q[i].xt,q[i].yt,q[i].zp+1)]-q[i].h;
cf[to_wei(q[i].xt,q[i].yp+1,q[i].zp+1)] = cf[to_wei(q[i].xt,q[i].yp+1,q[i].zp+1)]+q[i].h;
cf[to_wei(q[i].xp+1,q[i].yt,q[i].zp+1)] = cf[to_wei(q[i].xp+1,q[i].yt,q[i].zp+1)]+q[i].h;
cf[to_wei(q[i].xp+1,q[i].yp+1,q[i].zp+1)] = cf[to_wei(q[i].xp+1,q[i].yp+1,q[i].zp+1)]-q[i].h;
}
for(int i = 1; i<=n; i++) {
for(int k = 1; k<=c; k++) {
for(int j = 1; j<=m; j++) {
cf[to_wei(i,j,k)] = cf[to_wei(i,j-1,k)]+cf[to_wei(i,j,k)];
}
}
}
for(int j = 1; j<=m; j++) {
for(int k = 1; k<=c; k++) {
for(int i = 1; i<=n; i++) {
cf[to_wei(i,j,k)] = cf[to_wei(i-1,j,k)]+cf[to_wei(i,j,k)];
}
}
}
for(int i = 1; i<=n; i++) {
for(int j = 1; j<=m; j++) {
for(int k = 1; k<=c; k++) {
cf[to_wei(i,j,k)] = cf[to_wei(i,j,k-1)]+cf[to_wei(i,j,k)];
}
}
}
for(int i = 1; i<=n*m*c; i++) {
if(cf[i]>a[i]) {
return 1;
}
}
return 0;
}
/*check思路:
采用三维差分
首先看一维差分
直接在每一个区间的开始下标+权值,结束下标-权值即可。
例(所有例子下标都从1开始):
st:3 sp:6 num:8
0 0 8 0 0 0 -8 0
再把一行用前缀和加起来:
0 0 8 8 8 8 0 0
二维差分:
可以先合并每一行,在合并每一列。
可以利用合并每一行的时候在矩阵的下面一行做一个结束行。例:
矩阵:xst:3 xsp:6 yst:3 ysp:6 num:8
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 8 0 0 0 -8 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 -8 0 0 0 8 0
合并每一行:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 8 8 8 8 8 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 -8 -8 -8 -8 0 0
三维差分:先合并每一行,再合并每一列,最后合并每一个竖直的列(就是和高平行的所有列)
还是一样,可以在合并每一行每一列的时候做一个结束平面。
*/
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>c>>n>>m>>s;
for(int i = 1; i<=n*m*c; i++) {
cin>>a[i];
}
// cout<<to_wei(2,3,4);
for(int i = 1; i<=s; i++) {
cin>>q[i].xt>>q[i].xp>>q[i].yt>>q[i].yp>>q[i].zt>>q[i].zp>>q[i].h;
}
int l,r;
l = 1;
r = s;
while(l<=r) {
int mid;
mid = (l+r)/2;
if(check(mid)) {
r = mid-1;
} else {
l = mid+1;
}
}
cout<<l<<"\n";
return 0;
}
怎么调都不对,帮帮蒟蒻吧QAQ