欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

bzoj1128 Lam-lights

发布时间:2023/12/13 53 豆豆
生活随笔 收集整理的这篇文章主要介绍了 bzoj1128 Lam-lights 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

题目描述

对于一个长度为n的数列p,数列中任意两个数互质。准备一个无限长的储存器。然后从p1开始,把储存器中p1倍数位置都赋值为p1,把储存器中p2倍数位置都赋值为p2,把储存器中p3倍数位置都赋值为p3。。。把储存器中pn倍数位置都赋值为pn。最后求每个pi在储存器中出现的比例,用分数表示。

输入

n n个两两互质的数。

输出

输出n个分数

1<=n<=1000,1<=pi<=10^9

样例输入

3 2 3 5

样例输出

4/15 4/15 1/5

思路:如果从前往后做,之前统计过的会被之后的操作覆盖,所以我们从后往前统计.我们可以导出上面的式子(p为题目中输入的数)~但是,这道题需要输出最简分数,long long显然无法达到题目的要求(爆炸),所以我们需要写高精度.公式中第二部分可以用两个变量tmpa(分子),tmpb(分母)存乘积,边存边约分.

注意:若遇到1需要特判,因为1会占所有剩余的空隙,此时我们break掉并把后边的答案赋成0/1即可.

 

  1 #include <cstdio> 2 #define N 1010 3 #define M 1000000000 4 using namespace std; 5 int n,D; 6 struct gaojingdu{ 7 long long a[2010],clong; 8 void jinwei(){ 9 for(int i=1;i<clong;i++){ 10 a[i+1]+=a[i]/M; 11 a[i]%=M; 12 } 13 while(a[clong]>=M){ 14 clong++; 15 a[clong]=a[clong-1]/M; 16 a[clong-1]%=M; 17 } 18 while(a[clong]==0&&clong>1) clong--; 19 } 20 void print(){ 21 int i; 22 printf("%lld",a[clong]); 23 for(i=clong-1;i>=1;i--) 24 printf("%09lld",a[i]); 25 } 26 }; 27 int a[N]; 28 gaojingdu A[N],B[N]; 29 gaojingdu tmpa,tmpb,ret; 30 void initialize(gaojingdu &x,int y){ 31 x.clong=1; 32 x.a[1]=y; 33 } 34 int operator %(const gaojingdu &x,int y){ 35 long long ret=0; 36 for(int i=x.clong;i>=1;i--) 37 ret=(ret*M+x.a[i])%y; 38 return (int)ret; 39 } 40 gaojingdu operator *(const gaojingdu &x,int y){ 41 for(int i=1;i<=ret.clong;i++) 42 ret.a[i]=0; 43 ret.clong=x.clong; 44 for(int i=1;i<=x.clong;i++) 45 ret.a[i]=x.a[i]*y; 46 ret.jinwei(); 47 return ret; 48 } 49 gaojingdu operator /(const gaojingdu &x,int y){ 50 for(int i=1;i<=ret.clong;i++) 51 ret.a[i]=0; 52 long long tmp=0; 53 ret.clong=x.clong; 54 for(int i=x.clong;i>=1;i--){ 55 tmp=tmp*M+x.a[i]; 56 ret.a[i]=tmp/y; 57 tmp%=y; 58 } 59 ret.jinwei(); 60 return ret; 61 } 62 int gcd(int a,int b){ 63 if(a==0) 64 return b; 65 return gcd(b%a,a); 66 } 67 int gcd(int a,const gaojingdu &b){ 68 int tmp=b%a; 69 return gcd(a,tmp); 70 } 71 int main(){ 72 scanf("%d",&n); 73 int u,d,X,Y; 74 for(int i=1;i<=n;i++) 75 scanf("%d",&a[i]); 76 initialize(A[n],1);//A:答案分母 77 initialize(B[n],a[n]);//B:答案分子 78 initialize(tmpa,a[n]-1);//tmpa:后缀积的分子 79 initialize(tmpb,a[n]);//tmpb:后缀积的分母 80 for(int i=n-1;i>=1;i--){ 81 u=a[i]-1,d=a[i];//将要把u,d乘到tmp中 82 if(u!=0){ 83 X=gcd(u,tmpb);//分别对两组分子分母进行约分 84 Y=gcd(d,tmpa); 85 u/=X,d/=Y;//现在u与tmpb互质,d与tmpa互质 86 A[i]=tmpa/Y;//约分后代入 87 B[i]=tmpb*d; 88 tmpa=A[i]*u;//A[i]分母仍然是tmpa 89 tmpb=B[i]/X; 90 } 91 else{//遇到1时需要特判 92 D=i-1;//会把之前的覆盖 93 A[i]=tmpa;//*1不变 94 B[i]=tmpb; 95 break; 96 } 97 } 98 for(int i=1;i<=D;i++) 99 printf("0/1\n"); 100 for(int i=D+1;i<=n;i++){ 101 A[i].print(); 102 printf("/"); 103 B[i].print(); 104 printf("\n"); 105 } 106 return 0; 107 }

 

转载于:https://www.cnblogs.com/al76/p/8893769.html

总结

以上是生活随笔为你收集整理的bzoj1128 Lam-lights的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。