32pts求调,悬赏一关!
查看原帖
32pts求调,悬赏一关!
678447
CSPAK_Zhangxiuqi0011楼主2024/5/24 21:40
#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

2024/5/24 21:40
加载中...