Banzhuan
题目链接
题意:给你一个
n
∗
n
∗
n
n*n*n
n∗n∗n的空间,现在你需要在里面放多个
1
∗
1
∗
1
1*1*1
1∗1∗1的立方体,使得从上面,前面,侧面看过去都是一个正方形,在
(
x
,
y
,
z
)
(x,y,z)
(x,y,z)处放入立方体会产生花费
x
∗
y
2
∗
z
x*y^2*z
x∗y2∗z,当你放入位置的下方
(
x
,
y
,
z
−
1
)
(x,y,z-1)
(x,y,z−1)处是空的,立方体就会下坠至
(
x
1
,
y
1
,
z
1
+
1
)
(x_1,y_1,z_1+1)
(x1,y1,z1+1)处,当
(
x
1
,
y
1
,
z
1
)
(x_1,y_1,z_1)
(x1,y1,z1)处已经有立方体时,问未达成要求最小花费和最大花费分别为多少
解析:
①最大花费:首先是要全部填满,即放入
n
∗
n
∗
n
n*n*n
n∗n∗n个立方体,当放入
n
∗
n
∗
n
n*n*n
n∗n∗n个立方体时,x,y没法为花费最大化做出贡献,我们只能在z的大小做文章:当下方是空的时候,立方体会下落,我们可以使每一个立方体的初始z值都为n,此时使得花费最大,此时花费为
n
∗
n
∗
∑
x
=
1
n
x
∗
∑
y
=
1
n
y
2
n*n*\sum_{x=1}^{n}x*\sum_{y=1}^{n}y^2
n∗n∗x=1∑nx∗y=1∑ny2
②最小花费:为了从上向下看能是个
n
∗
n
n*n
n∗n正方形,最下层是必须的铺满的,为从前看
n
∗
n
n*n
n∗n的正方形,任意的y处都必须有n个立方体都叠在一起,花费计算公式为
x
∗
y
2
∗
z
x*y^2*z
x∗y2∗z,y和z是固定的,为使花费最小,我们应取x=1,从左边看和从前面看同理,取y=1,同时发现
(
1
,
1
,
z
)
(1,1,z)
(1,1,z)处不堆立方体也可达到效果,故最小花费为:
∑
x
=
1
n
x
∑
y
=
1
n
y
2
+
∑
z
=
2
n
z
∑
y
=
2
n
y
2
+
∑
x
=
2
n
x
∑
z
=
2
n
z
\sum_{x=1}^{n}x\sum_{y=1}^{n}y^2+\sum_{z=2}^{n}z\sum_{y=2}^{n}y^2+\sum_{x=2}^{n}x\sum_{z=2}^{n}z
x=1∑nxy=1∑ny2+z=2∑nzy=2∑ny2+x=2∑nxz=2∑nz
AcCode:
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#define int long long
#define ll __int128
#define eps 0.0000001
const int N = 1e6 + 100;
const int mod = 1e9+7;
#define T long long
inline T max(T a,T b){return (a>b)?a:b;}
inline T min(T a,T b){return (a<b)?a:b;}
inline int quick_pow(int a,int b){
int ans=1;
a%=mod;
while(b){
if(b&1) ans = ans*a%mod;
a = a*a%mod;
b>>=1;
}
return ans;
}
int mul(int a,int b){
int ans=0;
while(b){
if(b&1) ans = (ans+a)%mod;
a = (a+a)%mod;
b>>=1;
}
return ans;
}
signed main() {
int t; scanf("%lld", &t);
while (t--) {
int n;scanf("%lld",&n);
int max1 = mul(n,n);
int max2 = mul(n,n+1)*quick_pow(2,mod-2)%mod;
int max3 = mul(n,mul(n+1,2ll*n+1))*quick_pow(6,mod-2)%mod;
int maxans = mul(max1,mul(max2,max3));
int minans = mul(max2,max3);
int min2 = mul(n+2,n-1)*quick_pow(2,mod-2)%mod;
min2 = mul(min2,min2);
minans = (minans+min2)%mod;
minans = minans+mul(mul(n+2,n-1)*quick_pow(2,mod-2)%mod,(max3-1+mod)%mod);
printf("%lld\n%lld\n",minans%mod,maxans );
}
}