• 高精度分数类


    #include <cstdio>
    #include <iostream>
    #define LL long long 
    #define LDB long double
    using namespace std;
      
      const LL mo=1e6;
      LL lis[16001];
      
      struct bignum{
          LL a[8001];
          int len;
          
          void clear(){
            for (int i=0;i<=len;i++)    
              a[i]=0;
            len=0;
        }
        
        void one(){
          clear();
          a[0]=1;
        }
        
        void cpy(bignum &b){
          clear();
          len=b.len;
          for (int i=0;i<=len;i++)
            a[i]=b.a[i];
        }    
        
        void outp(){
          printf("%lld",a[len]);
          for (int i=len-1;i>=0;i--) printf("%06lld",a[i]);
        }
        
        void sub(bignum &b){
          for (int i=0;i<=len;i++){
              if (i<=b.len) a[i]-=b.a[i];
              if (a[i]<0){a[i]+=mo;a[i+1]--;}
          }
          while (len>0&&!a[len]) len--;
        }
        
        void add(bignum &b){
          len=max(len,b.len);
          for (int i=0;i<=len;i++)
            a[i]+=b.a[i];
          for (int i=0;i<=len;i++){
              a[i+1]+=a[i]/mo;
              a[i]%=mo;
          }
          while (a[len+1]){
              len++;
              a[len+1]+=a[len]/mo;a[len]%=mo;
          }
        }
        
        void mul(bignum &b){
          for (int i=0;i<=len+b.len;i++) lis[i]=0;
          for (int i=0;i<=len;i++)
            for (int j=0;j<=b.len;j++)
              lis[i+j]+=a[i]*b.a[j];
              
          len+=b.len;
          for (int i=0;i<=len;i++) a[i]=lis[i];
          for (int i=0;i<=len;i++){
              a[i+1]+=a[i]/mo;
              a[i]%=mo;
          }
          while (a[len+1]){
              len++;
              a[len+1]+=a[len]/mo;a[len]%=mo;
          }
          while (len>0&&!a[len])
            len--;
        }
            
        void mul(LL num){
          for (int i=0;i<=len;i++)
            a[i]*=num;
          for (int i=0;i<=len;i++)
            a[i+1]+=a[i]/mo,a[i]%=mo;
          while (a[len+1]){
              len++;
            a[len+1]+=a[len]/mo;a[len]%=mo;
          }
          while (len>0&&!a[len])
            len--;
        }
        
        void div(LL num){
          for (int i=len;i>=0;i--){
              if (i) a[i-1]+=a[i]%num*mo;
            a[i]/=num;
          }
          while (len>0&&!a[len]) len--;
        }
        
        void add(LL num){
          a[0]+=num;
          int po=0;
          while (a[po]>=mo){
              a[po+1]+=a[po]/mo;a[po]%=mo;
              po++;
          }
          while (len>0&&!a[len]) len--;
        }
        
        void sub(LL num){
          a[0]-=num;
          int po=0;
          while (a[po]<0){
              LL bas=(-a[po]-1)/mo+1;
              a[po+1]-=bas;a[po]+=bas*mo;
              po++;
          }
          while (a[len+1]) len++;
        }
        
        int equal(bignum &b){
          if (len!=b.len) return(0);
          for (int i=len;i>=0;i--)
            if (a[i]!=b.a[i]) return(0);
          return(1);
        }
        
        int bigger_or_equalto(bignum&b){
          if (len>b.len) return(1);
          if (len<b.len) return(0);
          for (int i=len;i>=0;i--){
              if (a[i]>b.a[i]) return(1);
              if (a[i]<b.a[i]) return(0);
          }
          return(1);
        }
        
        int equal_zero(){
          return(len==0&&a[0]==0);
        }
        
        int bigger(bignum&b){
          if (len>b.len) return(1);
          if (len<b.len) return(0);
          for (int i=len;i>=0;i--){
              if (a[i]>b.a[i]) return(1);
              if (a[i]<b.a[i]) return(0);
          }
          return(0);
        }
      }c,tmp,bi1,bi2;
      
      int getdiv(bignum &a,bignum&b){
          if (a.len<b.len) return(0);
          LDB numa=a.a[a.len];
          if (a.len) numa*=mo,numa+=a.a[a.len-1];
          int powa=max(0,a.len-1);
          LDB numb=b.a[b.len];
          if (b.len) numb*=mo,numb+=b.a[b.len-1];
          int powb=max(0,b.len-1);
          if (powa-powb==1) 
            numa*=mo;
          return(numa/numb-1);
      }
      
      void divs(bignum &a,bignum &b){
        tmp.clear();
        int nlen=-1;
        for (int i=a.len;i>=0;i--){
          tmp.mul(mo);tmp.add(a.a[i]);
          a.a[i]=0;
          while (getdiv(tmp,b)){
            a.a[i]+=getdiv(tmp,b);
            if (a.a[i]!=0&&nlen==-1)
                nlen=i;
            bi1.cpy(b);bi1.mul(getdiv(tmp,b));
            tmp.sub(bi1);
          }
          while (tmp.bigger_or_equalto(b)){
              if (nlen==-1)
                nlen=i;
              tmp.sub(b),a.a[i]++;
          }
        }
        a.len=nlen;
      }
      
      bignum gcd(bignum x,bignum y){
          if (x.equal_zero()) return(y);
          
          LL pow2=0;
          while (!x.equal(y)){
            if ((x.a[0]%2==0)&&(y.a[0]%2==0)){
                x.div(2);y.div(2);
            pow2++;
            continue;
          }
          if (x.a[0]%2==0){
            x.div(2);continue;
          }
          if (y.a[0]%2==0){
              y.div(2);continue;
          }
            if (y.bigger(x))    
              swap(x,y);
            x.sub(y);
        }
        for (int i=1;i<=pow2;i++)
          x.mul(2);
        return(x);
      }
      
      struct fact{
          bignum a,b;
          int sig;
          
          void set(LL n){
            sig=1;    
            if (n<0) n*=-1,sig*=-1;
          a.clear();a.a[0]=n;
          b.one();
        }
        
        void cpy(fact &ano){
          a.cpy(ano.a);b.cpy(ano.b);
          sig=ano.sig;
        }
        
        void add(fact &ano){
          bi1.cpy(a);bi1.mul(ano.b);
          bi2.cpy(ano.a);bi2.mul(b);
          if (sig==ano.sig){
              bi1.add(bi2);
              a.cpy(bi1);
          }else{
              if (sig==-1&&ano.sig==1)
                swap(bi1,bi2);
            if (bi1.bigger(bi2)){
              bi1.sub(bi2);    
              a.cpy(bi1);
              sig=1;
            }else{
              bi2.sub(bi1);
              a.cpy(bi2);
              sig=-1;
            }
          }
          b.mul(ano.b);
        }
    
        void sub(LL num){
          tmp.cpy(b);tmp.mul(num);
          if (sig==-1){
              a.add(tmp);
          }else{
              if (a.bigger(tmp))
                a.sub(tmp);
            else{
              tmp.sub(a);
              a.cpy(tmp);
                sig=-1;      
            }
          }
        }
        
        void add(LL num){
          tmp.cpy(b);tmp.mul(num);
          if (sig==1){
              a.add(tmp);
          }else{
              if (a.bigger(tmp))
                a.sub(tmp);
            else{
              tmp.sub(a);
              a.cpy(tmp);
              sig=1;    
            }  
          }
        }
            
        void mul(LL num){
          if (num<0) sig*=-1,num*=-1;
          a.mul(num);
        }
        
        void div(LL num){
          if (num<0) sig*=-1,num*=-1;
          b.mul(num);    
        }
        
        void outp(int cas){
          printf("Case #%d: ",cas);
          if (sig==-1) printf("-"); 
          c.clear();    
          c=gcd(a,b);
          divs(a,c);
          divs(b,c);
          a.outp();printf(" ");b.outp();
        }
      }ans1,ans2,ans3,bas;
      
      int bigger(fact &a,fact &b){
          if (a.sig==1&&b.sig==-1) 
            return(1);
          if (a.sig==-1&&b.sig==1)
            return(0);
          bi1.cpy(a.a);bi1.mul(b.b);
          bi2.cpy(b.a);bi2.mul(a.b);
          if (bi1.bigger(bi2)){
            if (a.sig==1) return(1);else
            return(0);    
        }else{
          if (a.sig==-1) return(1);else
            return(0);        
        }
      }
      
      int T,multab[2333][2],divtab[2333][2];
      LL n,m,num[2333];
      char opt[2333][11];
    
      int main(){      
          scanf("%d",&T);
          for (int cas=1;cas<=T;cas++){
            scanf("%lld%lld",&n,&m);
            LL posi=0,nega=0;
            for (int i=0;i<=1000;i++) multab[i][0]=multab[i][1]=divtab[i][0]=divtab[i][1]=0;
            int allposi=1,mul0=0,mulsig=1;
          for (int i=1;i<=m;i++){
    
              scanf("%s%lld",&opt[i],&num[i]);
              if (opt[i][0]=='+'){
                if (num[i]>0)    posi+=num[i];else
                nega-=num[i];
            }else
            if (opt[i][0]=='-'){
              if (num[i]>0)    nega+=num[i];else
              posi-=num[i];
            }else
            if (opt[i][0]=='*'){
              if (num[i]>0) multab[num[i]][0]++;else
                multab[-num[i]][1]++;
              if (num[i]==0) mul0=1;
              if (num[i]<0) allposi=0,mulsig*=-1;
            }else{
              if (num[i]>0) divtab[num[i]][0]++;else
                divtab[-num[i]][1]++;
              if (num[i]<0) allposi=0;
            }
          }
            
          if (allposi){
              if (mul0){
                ans1.set(posi);     
                for (int i=1;i<=1000;i++)
                  for(int j=1;j<=multab[i][0];j++)
                    ans1.mul(i);
                ans1.outp(cas);
            }else{
              ans1.set(n);
              ans1.sub(nega);
              for (int i=1;i<=1000;i++)
                for (int j=1;j<=divtab[i][0];j++)
                  ans1.div(i);
              ans1.add(posi);
              for (int i=1;i<=1000;i++)
                  for(int j=1;j<=multab[i][0];j++)
                    ans1.mul(i);
                    
              ans2.set(n);
              ans2.add(posi);
              for (int i=1;i<=1000;i++)
                  for(int j=1;j<=multab[i][0];j++)
                    ans2.mul(i);          
                ans2.sub(nega);
              for (int i=1;i<=1000;i++)
                for (int j=1;j<=divtab[i][0];j++)
                  ans2.div(i);
             
              if (bigger(ans2,ans1)) 
                ans1.cpy(ans2);
                
              ans2.set(n);
              for (int i=1;i<=1000;i++)
                for (int j=1;j<=divtab[i][0];j++)
                  ans2.div(i);
              ans2.add(posi);
              for (int i=1;i<=1000;i++)
                  for(int j=1;j<=multab[i][0];j++)
                    ans2.mul(i); 
                ans2.sub(nega);
                         
              if (bigger(ans2,ans1)) 
                ans1.cpy(ans2);
                
              ans2.set(n);
              for (int i=1;i<=1000;i++)
                  for(int j=1;j<=multab[i][0];j++)
                    ans2.mul(i); 
                ans2.sub(nega);
              for (int i=1;i<=1000;i++)
                for (int j=1;j<=divtab[i][0];j++)
                  ans2.div(i);
              ans2.add(posi);
                         
              if (bigger(ans2,ans1)) 
                ans1.cpy(ans2);          
                
              ans1.outp(cas);
            }
          }else{
              bas.set(1);
              for (int i=1;i<=1000;i++){
                for (int j=1;j<=multab[i][0];j++) bas.mul(i);      
                for (int j=1;j<=multab[i][1];j++) bas.mul(-i);      
            }
              for (int i=1;i<=1000;i++){
                for (int j=1;j<=divtab[i][0];j++) bas.div(i);      
                for (int j=1;j<=divtab[i][1];j++) bas.div(-i);
            }
            if (mul0) ans1.set(0);else ans1.cpy(bas),ans1.mul(n);
            
            bas.set(1);
            for (int i=1;i<=1000;i++){
                for (int j=1;j<=multab[i][0];j++) bas.mul(i);      
                for (int j=1;j<=multab[i][1];j++) bas.mul(i);      
            }
            
            int mini=1e9;
            for (int i=1;i<=1000;i++) if (multab[i][1]) mini=min(mini,i);
            for (int i=1;i<=1000;i++) if (divtab[i][1]) mini=min(mini,i);
            
            if (mulsig==1){
              ans2.cpy(bas);ans2.mul(posi);
              ans3.cpy(bas);ans3.mul(nega);ans3.div(mini);
              ans1.add(ans2);ans1.add(ans3);
              ans1.outp(cas);
            }else{
              ans2.cpy(bas);ans2.mul(nega);
              ans3.cpy(bas);ans3.mul(posi);ans3.div(mini);
              ans1.add(ans2);ans1.add(ans3);
              ans1.outp(cas);    
            }
          }
          printf("
    ");
        }
      }
  • 相关阅读:
    ceph概述
    docker网络
    ceph部署
    K8s集群搭建(二)
    K8s架构
    K8s集群搭建(一)
    Kubernetes介绍
    虚拟化网络管理(二)
    virt-manager创建虚拟机
    C#中TransactionScope的使用方法和原理
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/8657026.html
Copyright © 2020-2023  润新知