【?】高精版同余方程
就是一个蒟蒻无聊搞的乱七八糟的东西 想法很美好 结果真正打的时候发现有一堆要考虑的细节 几乎崩溃
主要就是判断一下为负时的各种情况 其实都差不多 应该有更好的方法 但蒟蒻暂时只能想到这种每种情况讨论一下的方法
然后死于在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 }