题解 P5456 【[THUPC2018]蛋糕】
一开始做这道题的时候有点懵,在网上能找到的题解几乎都是
这道题放在了组合计数专题的例题中,开始的时候其实我没感觉这道题跟组合数有多大关系,后来想想,如果把四维换成
分析
这道题求的是四维的情况,直接做似乎不可行?不妨先考虑三维的情况,那么这道题就退化成了一个小学数学题:有一个由
Ⅰ.考虑
其余皆为
Ⅱ.如果
其余皆为
Ⅲ.如果
其余皆为
Ⅳ.如果
其余皆为
以上我们推出了三维物体的全部规律。
那么四维怎么办呢?仍然按照有
先
#define A (a-2)%mod
#define B (b-2)%mod
#define C (c-2)%mod
#define D (d-2)%mod
Ⅰ.四维物体有
ans[0]=A*B*C*D;
ans[1]=2*(A*B*C+A*B*D+A*C*D+B*C*D)%mod;
ans[2]=4*(A*B+A*C+A*D+B*C+B*D+C*D)%mod;
ans[3]=8*(A+B+C+D)%mod;
ans[4]=16;
Ⅱ.四维物体有
ans[2]=A*B*C%mod;
ans[3]=2*(A*B+A*C+B*C)%mod;
ans[4]=4*(A+B+C)%mod;
ans[5]=8;
Ⅲ.四维物体有
ans[4]=(a-2)*(b-2)%mod;
ans[5]=2*(a+b-4)%mod;
ans[6]=4;
Ⅳ.四维物体有
ans[6]=(a%mod-2%mod)%mod;
ans[7]=2;
Ⅴ.四维物体有
ans[8]=1;
直到这里,我们就推导出了完整的规律。
本质上跟
AC代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int mod=2148473648;
#define A (a-2)%mod
#define B (b-2)%mod
#define C (c-2)%mod
#define D (d-2)%mod
int ans[9],a,b,c,d,cnt,f[5];
signed main()
{
// freopen("data.in","r",stdin);
// freopen("my.out","w",stdout);
int T;
scanf("%lld",&T);
while(T--)
{
memset(ans,0,sizeof ans);
memset(f,0,sizeof f);
cnt=0;
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
if(a!=1)f[++cnt]=a;
if(b!=1)f[++cnt]=b;
if(c!=1)f[++cnt]=c;
if(d!=1)f[++cnt]=d;
if(cnt==4)
{
ans[0]=A*B*C*D;
ans[1]=2*(A*B*C+A*B*D+A*C*D+B*C*D)%mod;
ans[2]=4*(A*B+A*C+A*D+B*C+B*D+C*D)%mod;
ans[3]=8*(A+B+C+D)%mod;
ans[4]=16;
for(int i=0;i<=8;i++)
printf("%lld ",ans[i]);
continue;
}
if(cnt==3)
{
a=f[1],b=f[2],c=f[3];
ans[2]=A*B*C%mod;
ans[3]=2*(A*B+A*C+B*C)%mod;
ans[4]=4*(A+B+C)%mod;
ans[5]=8;
for(int i=0;i<=8;i++)
printf("%lld ",ans[i]);
continue;
}
if(cnt==2)
{
a=f[1],b=f[2];
ans[4]=(a-2)*(b-2)%mod;
ans[5]=2*(a+b-4)%mod;
ans[6]=4;
for(int i=0;i<=8;i++)
printf("%lld ",ans[i]);
continue;
}
if(cnt==1)
{
a=f[1];
ans[6]=(a%mod-2%mod)%mod;
ans[7]=2;
for(int i=0;i<=8;i++)
printf("%lld ",ans[i]);
continue;
}
if(cnt==0)
{
ans[8]=1;
for(int i=0;i<=8;i++)
printf("%lld ",ans[i]);
continue;
}
}
return 0;
}
扩展
其实这道题过水了,完全可以扩展到
组合计数