【?】高精版同余方程

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

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

然后死于在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 }

 

posted @ 2019-05-12 17:59  委屈的咸鱼鱼鱼鱼  阅读(152)  评论(0编辑  收藏  举报