2013 2013 ACM/ICPC Asia Regional Changsha Online - H Hypersphere

来源:互联网 发布:怎么在淘宝买翻墙 编辑:程序博客网 时间:2024/05/22 06:13

在k维空间里有个半径为r的打球,现在把它分解成一个一个半径为1的球,当分解出k个球,球就要消失,问最后有多少个小球。大球半径为

l+sqrt((l-1)*l);

很显然就是一共能产生多少个小球来对k取余.


至于k维空间球体的体积,维基百科上有,有一个很复杂的公式,所幸,这里得分子分母都有那个复杂的系数,也就是没有了,最后求得就是floor((l+sqrt(l*(l-1)))^k)%k


这和长沙邀请赛的A题,几乎一模一样,只是这里向下取整,邀请赛向上。其实一样,向上取整的答案-1就行了。解法在《挑战程序设计竞赛》的268页有,在别人的博客也有==


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;typedef long long ll;struct Matrix{    ll m[2][2];}E,D;ll mod,n,l,k;inline Matrix Mul(Matrix a,Matrix b){    Matrix ans;    for(int i=0;i<2;i++)        for(int j=0;j<2;j++)        {            ans.m[i][j]=0;            for(int k=0;k<2;k++)            {                ans.m[i][j]+=a.m[i][k]*b.m[k][j]%mod;                ans.m[i][j]%=mod;            }        }    return ans;}inline Matrix Pow(Matrix a,int n){    Matrix ans=E,t=a;    while(n)    {        if(n%2) ans=Mul(ans,t);        n/=2;        t=Mul(t,t);    }    return ans;}int main(){    E.m[0][0]=E.m[1][1]=1;    E.m[0][1]=E.m[1][0]=0;    while(~scanf("%lld%lld",&k,&l))    {        mod=n=k;        D.m[0][0]=l%mod;        D.m[0][1]=l*(l-1)%mod;        D.m[1][0]=1;        D.m[1][1]=l%mod;        Matrix ans=Pow(D,n);        printf("%lld\n",(ans.m[0][0]*2+mod-1)%mod);    }    return 0;}



原创粉丝点击