bzoj1128 Lam-lights
生活随笔
收集整理的這篇文章主要介紹了
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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信亲属卡怎么消费?收到微信亲属卡怎么用
- 下一篇: 微信亲属卡支付失败是怎么回事?支付失败原