hdu 5047 Sawtooth 2014 ACM/ICPC Asia Regional Shanghai Online 数学

来源:互联网 发布:微信数据保存到sd卡 编辑:程序博客网 时间:2024/05/04 07:38

题目链接:hdu 5047

        问n个M型的折线段最多能把一个平面分成多少个部分


        通过数学推导可以发现结果为 8*n*n-7*n+1

        本题的n的范围达到了10^12,连long long都爆了,队友准备直接java大数的结果这题卡时限卡的很紧,java会T。因此需要手敲高精度。

        但是这题的数据范围最大只到10^24,因此可以用三个long long的分别表示从高到低的9位的数,然后敲高精度,能很好的降低代码的复杂度

/****************************************************** * File Name:   1006.cpp * Author:      kojimai * Creater Time:2014年09月27日 星期六 14时36分54秒******************************************************/#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<iostream>using namespace std;const long long mod= 1e9;long long l1,l2,l3;long long al,bl,cl;void mul(){long long t1=0,t2=0,t3=0;long long t;t1=l1*l1;t=t1/mod;t1=t1%mod;t2=l2*l1+t;t=t2/mod;t2=t2%mod;t3+=t;//cout<<"t3="<<t3<<" t2="<<t2<<" t1="<<t1<<endl;t2+=l2*l1;t=t2/mod;t2%=mod;t3+=l2*l2+t;l1=t1;l2=t2;l3=t3;}void muln(int x){l1=l1*x;long long t=l1/mod;l1%=mod;l2=x*l2+t;t=l2/mod;l2%=mod;l3=l3*x+t;}void add(){long long t;al=al+l1;t=al/mod;al%=mod;bl=bl+l2+t;t=bl/mod;bl%=mod;cl=cl+l3+t;}void Minus(){long long t=0;al=al-l1;if(al<0){al=al+mod;bl-=1;}bl=bl-l2;if(bl<0){bl=bl+mod;cl-=1;}cl=cl-l3;}void solve(long long n){cl=bl=0;al=1;l1=n%mod;l2=n/mod;l3=0;mul();//cout<<l3<<' '<<l2<<' '<<l1<<endl;muln(8);//cout<<l3<<' '<<l2<<' '<<l1<<endl;add();//cout<<cl<<' '<<bl<<' '<<al<<endl;l1=n%mod;l2=n/mod;l3=0;//cout<<l3<<' '<<l2<<' '<<l1<<endl;muln(7);//cout<<l3<<' '<<l2<<' '<<l1<<endl;Minus();//cout<<cl<<' '<<bl<<' '<<al<<endl;if(cl)//cout<<cl<<' '<<bl<<' '<<al<<endl;//printf("%I64d%09I64d%09I64d\n",cl,bl,al);printf("%I64d%09I64d%09I64d\n",cl,bl,al);else if(bl)//cout<<bl<<' '<<al<<endl;//printf("%I64d%09I64d\n",bl,al);printf("%I64d%09I64d\n",bl,al);elsecout<<al<<endl;return;}int main(){int keng,ca=1;scanf("%d",&keng);long long n;while(keng--){//scanf("%I64d",&n);cin>>n;printf("Case #%d: ",ca++);if(n==0)cout<<1<<endl;elsesolve(n);}return 0;}


0 0
原创粉丝点击