zoukankan      html  css  js  c++  java
  • 【?】高精版同余方程

    就是一个蒟蒻无聊搞的乱七八糟的东西 想法很美好 结果真正打的时候发现有一堆要考虑的细节 几乎崩溃

    主要就是判断一下为负时的各种情况 其实都差不多 应该有更好的方法 但蒟蒻暂时只能想到这种每种情况讨论一下的方法

    然后死于在mzoj提交时我的数据格式 导致无数次的编译错误

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define ll long long
      4 #define rg register
      5 const int N=1000,base=10000,power=4,K=100,P=9901;
      6 char a[N],b[N],E[1]={'1'};
      7 template <class t>void rd(t &x)
      8 {
      9     x=0;int w=0;char ch=0;
     10     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
     11     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
     12     x=w?-x:x;
     13 }
     14 
     15 struct num{
     16     int a[N];
     17     bool f=0;
     18     num(){memset(a,0,sizeof(a));}
     19     num(char *s)
     20     {
     21         memset(a,0,sizeof(a));
     22         int len=strlen(s);
     23         a[0]=(len+power-1)/power;
     24         for(rg int i=0,t=0,w;i<len;++i,w*=10)
     25         {
     26             if(i%power==0) w=1,++t;
     27             a[t]+=w*(s[i]-'0');
     28         }
     29     }
     30     void add(int k) {if(k||a[0]) a[++a[0]]=k;}
     31     void re() {reverse(a+1,a+1+a[0]);}
     32     void print()
     33     {
     34         printf("%d",a[a[0]]);
     35         for(rg int i=a[0]-1;i>0;--i) printf("%0*d",power,a[i]);
     36     }
     37 }p,q,x,y,e;
     38 
     39 bool operator <(const num &p,const num &q)
     40 {
     41     if(p.f&&!q.f) return 1;
     42     if(!p.f&&q.f) return 0;
     43     if(!p.f&&!q.f)
     44     {
     45         if(p.a[0]<q.a[0]) return 1;
     46         if(p.a[0]>q.a[0]) return 0;
     47         for(rg int i=p.a[0];i>0;--i)
     48         if(p.a[i]!=q.a[i]) return p.a[i]<q.a[i];
     49         return 0;
     50     }
     51     if(p.f&&q.f)
     52     {
     53         if(p.a[0]<q.a[0]) return 0;
     54         if(p.a[0]>q.a[0]) return 1;
     55         for(rg int i=p.a[0];i>0;--i)
     56         if(p.a[i]!=q.a[i]) return p.a[i]>q.a[i];
     57         return 0;
     58     }
     59 }
     60 
     61 
     62 num operator +(const num &p,const num &q)//高精+
     63 {
     64     num c;
     65     c.a[0]=max(p.a[0],q.a[0]);
     66     for(rg int i=1;i<=c.a[0];++i)
     67     {
     68         c.a[i]+=p.a[i]+q.a[i];
     69         c.a[i+1]+=c.a[i]/base,c.a[i]%=base;
     70     }
     71     if(c.a[c.a[0]+1]) ++c.a[0];
     72     return c;
     73 }
     74 
     75 num operator -(const num &p,const num &q)
     76 {
     77     num c=p;
     78     for(int i=1;i<=q.a[0];++i)
     79     {
     80         c.a[i]-=q.a[i];
     81         if(c.a[i]<0) c.a[i]+=base,--c.a[i+1];
     82     }
     83     while(c.a[0]>0&&!c.a[c.a[0]]) --c.a[0];
     84     return c;
     85 }
     86 
     87 num operator %(const num &p,const num &q)
     88 {
     89     num x,y;
     90     for(int i=p.a[0];i>=1;--i)
     91     {
     92         y.add(p.a[i]),y.re();
     93         while(!(y<q)) y=y-q;
     94         y.re();
     95     }
     96     y.re(),y.f=p.f;
     97     return y;
     98 }
     99 
    100 num operator *(const num &p,const num &q)//高精*
    101 {
    102     num c;
    103     c.a[0]=p.a[0]+q.a[0]-1;
    104     for(rg int i=1;i<=p.a[0];++i)
    105     for(rg int j=1;j<=q.a[0];++j)
    106     {
    107         c.a[i+j-1]+=p.a[i]*q.a[j];
    108         c.a[i+j]+=c.a[i+j-1]/base,c.a[i+j-1]%=base;
    109     }
    110     //while(c.a[0]>1&&!c.a[c.a[0]]) --c.a[0];
    111     while(c.a[c.a[0]+1]) ++c.a[0];
    112     return c;
    113 }
    114 
    115 num operator / (const num &p, const num &q)
    116 {  
    117     num x, y;  
    118     for (int i = p.a[0];i >= 1;--i)                       //从最高位开始取数  
    119     {  
    120         y.add(p.a[i]);  //把数添到末尾(最低位),这时候是高位在前,低位在后  
    121         y.re();           //把数反过来,变为统一的存储方式:低位在前,高位在后  
    122         while ( !(y < q) )         //大于等于除数的时候,如果小于的话,其实答案上的该位就是初始的“0”  
    123             y = y - q, ++x.a[i];   //看能减几个除数,减几次,答案上该位就加几次。  
    124         y.re();                    //将数反过来,为下一次添数做准备  
    125     }  
    126     x.a[0] = p.a[0];
    127     while (x.a[0] > 0 && !x.a[x.a[0]]) --x.a[0]; 
    128     return x;  
    129 }
    130 
    131 void exgcd(num p,num q,num &x,num &y)
    132 {
    133     if(!q.a[0]) {x=e,y=q;return;}
    134     exgcd(q,p%q,x,y);
    135     num t=x,tt=p/q;tt=tt*y,tt.f=y.f;
    136     x=y;
    137     if(t.f&&tt.f)
    138     {
    139         if(t<tt) y=tt-t,y.f=0;
    140         else y=t-tt,y.f=1;
    141     }
    142     else if(t.f&&!tt.f) y=t+tt,y.f=1;
    143     else if(!t.f&&tt.f) y=t+tt,y.f=0;
    144     else if(!t.f&&!tt.f)
    145     {
    146         if(!(t<tt)) y=t-tt,y.f=0;
    147         else y=tt-t,y.f=1;
    148     }
    149 }
    150 
    151 int main()
    152 {
    153     //freopen("in.txt","r",stdin);
    154     //freopen("out.txt","w",stdout);
    155     e=num(E);
    156     scanf("%s%s",&a,&b);
    157     reverse(a,a+strlen(a));
    158     reverse(b,b+strlen(b));//反转!!! 
    159     p=num(a),q=num(b);
    160     exgcd(p,q,x,y);
    161     x=x%b;
    162     if(x.f) x=b-x;
    163     x=x%b;
    164     x.print();
    165     return 0;
    166 }
  • 相关阅读:
    Mac 虚拟机VMware Fusion显示内部错误的解决方法
    Linux系统中的引导过程与服务控制
    linux系统中如何删除lvm分区
    Linux命令下: LVM逻辑卷配置过程详解(创建,增加,减少,删除,卸载)
    解决:rm: 无法删除"tomcat": 设备或资源忙
    LVM操作过程
    Linux命令下进行硬盘挂载、分区、删除分区,格式化,卸载方法
    finger 命令查询用户名、主目录、停滞时间、登录时间
    【MySQL】MySQL5.7传统复制切换为GTID复制
    深入理解MySQL系列之锁
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/10853078.html
Copyright © 2011-2022 走看看