2021-08-03

Banzhuan
题目链接
题意:给你一个 n ∗ n ∗ n n*n*n nnn的空间,现在你需要在里面放多个 1 ∗ 1 ∗ 1 1*1*1 111的立方体,使得从上面,前面,侧面看过去都是一个正方形,在 ( x , y , z ) (x,y,z) (x,y,z)处放入立方体会产生花费 x ∗ y 2 ∗ z x*y^2*z xy2z,当你放入位置的下方 ( x , y , z − 1 ) (x,y,z-1) (x,y,z1)处是空的,立方体就会下坠至 ( 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 nnn个立方体,当放入 n ∗ n ∗ n n*n*n nnn个立方体时,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 nnx=1nxy=1ny2
②最小花费:为了从上向下看能是个 n ∗ n n*n nn正方形,最下层是必须的铺满的,为从前看 n ∗ n n*n nn的正方形,任意的y处都必须有n个立方体都叠在一起,花费计算公式为 x ∗ y 2 ∗ z x*y^2*z xy2z,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=1nxy=1ny2+z=2nzy=2ny2+x=2nxz=2nz

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 );
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值