-
个人简介
高精度运算 *
#include<bits/stdc++.h> using namespace std; //complex是stl自带的定义复数的容器 typedef complex<double> cp; #define N 2097153 //pie表示圆周率π const double pie=acos(-1); int n; cp a[N],b[N]; int rev[N],ans[N]; char s1[N],s2[N]; //读入优化 int read(){ int sum=0,f=1; char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();} return sum*f; } //初始化每个位置最终到达的位置 { int len=1<<k; for(int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1)); } //a表示要操作的系数,n表示序列长度 //若flag为1,则表示FFT,为-1则为IFFT(需要求倒数) void fft(cp *a,int n,int flag){ for(int i=0;i<n;i++) { //i小于rev[i]时才交换,防止同一个元素交换两次,回到它原来的位置。 if(i<rev[i])swap(a[i],a[rev[i]]); } for(int h=1;h<n;h*=2)//h是准备合并序列的长度的二分之一 { cp wn=exp(cp(0,flag*pie/h));//求单位根w_n^1 for(int j=0;j<n;j+=h*2)//j表示合并到了哪一位 { cp w(1,0); for(int k=j;k<j+h;k++)//只扫左半部分,得到右半部分的答案 { cp x=a[k]; cp y=w*a[k+h]; a[k]=x+y; //这两步是蝴蝶变换 a[k+h]=x-y; w*=wn; //求w_n^k } } } //判断是否是FFT还是IFFT if(flag==-1) for(int i=0;i<n;i++) a[i]/=n; } int main(){ n=read(); scanf("%s%s",s1,s2); //读入的数的每一位看成多项式的一项,保存在复数的实部 for(int i=0;i<n;i++)a[i]=(double)(s1[n-i-1]-'0'); for(int i=0;i<n;i++)b[i]=(double)(s2[n-i-1]-'0'); //k表示转化成二进制的位数 int k=1,s=2; while((1<<k)<2*n-1)k++,s<<=1; init(k); //FFT 把a的系数表示转化为点值表示 fft(a,s,1); //FFT 把b的系数表示转化为点值表示 fft(b,s,1); //FFT 两个多项式的点值表示相乘 for(int i=0;i<s;i++) a[i]*=b[i]; //IFFT 把这个点值表示转化为系数表示 fft(a,s,-1); //保存答案的每一位(注意进位) for(int i=0;i<s;i++) { //取实数四舍五入,此时虚数部分应当为0或由于浮点误差接近0 ans[i]+=(int)(a[i].real()+0.5); ans[i+1]+=ans[i]/10; ans[i]%=10; } while(!ans[s]&&s>-1)s--; if(s==-1)printf("0"); else for(int i=s;i>=0;i--) printf("%d",ans[i]); return 0; //除 ```cpp #include<bits/stdc++.h> using namespace std; int main(){ string a1; unsigned long long c,A[5001],C[5001],lena,l; cin>>a1>>c; if(a1=="0"){ cout<<0; return 0; } lena=a1.length(); for(int i=0;i<lena;i++){ A[lena-i]=a1[i]-'0'; } for(int i=lena;i>=1;i--){ if(A[i]>=c){ A[i-1]+=(A[i]%c)*10; C[i]=A[i]/c; } else{ A[i-1]+=A[i]*10; } } l=lena; for(int i=lena;i>=1;i--){ if(C[i]!=0){ break; } else{ l--; } } for(int i=l;i>=1;i--){ cout<<C[i]; } return 0; } ```cpp 加法 #include<bits/stdc++.h> using namespace std; char a[510],b[510],n,m; int c[510],d[510],e[510]; int lena,lenb,len; int main() { scanf("%s",a+1); scanf("%s",b+1); lena=strlen(a+1); lenb=strlen(b+1); len=max(lena,lenb); for(int i=1;i<=lena;i++) c[lena-i+1]=a[i]-48; for(int i=1;i<=lenb;i++) d[lenb-i+1]=b[i]-48; for(int i=1;i<=509;i++) e[i] = 0; for(int i=1;i<=len;i++) { int k = c[i]+d[i]+e[i]; int t = k%10; int p = k/10; e[i] = t; e[i+1] += p; } if(e[len+1]>0) len++; for(int i=len;i>=1;i--) printf("%d",e[i]); }减法 ```cpp #include<bits/stdc++.h> using namespace std; char sa[111111111],sb[111111111],tmp[11111111]; int a[11111111],b[11111111],c[11111111]; int main(){ memset(c,0,sizeof(c)); scanf("%s%s",sa,sb); int la=strlen(sa),lb=strlen(sb); if(la<lb||((la==lb)&&strcmp(sa,sb)<0)){ strcpy(tmp,sa); strcpy(sa,sb); strcpy(sb,tmp); swap(la,lb); printf("-"); } int lc=la>lb?la:lb; for(int i=0;i<la;i++) a[la-i]=sa[i]-'0'; for(int i=0;i<lb;i++) b[lb-i]=sb[i]-'0'; for(int i=1;i<=lc;i++){ if(a[i]<b[i]){ a[i]+=10; a[i+1]--; } c[i]=a[i]-b[i]; } while(c[lc]==0&&lc>1) lc--; for(int i=lc;i>0;i--) printf("%d",c[i]); return 0; }
}```
-
通过的题目
-
最近活动
This person is lazy and didn't join any contests or homework. -
最近编写的题解
This person is lazy and didn't write any solutions. -
Stat
-
Rating
题目标签
- 模拟
- 13
- NOIp 普及组
- 10
- 枚举
- 6
- 暴力
- 6
- 字符串
- 3
- 2004
- 2
- 2005
- 2
- O2优化
- 2
- 数论
- 2
- 数学
- 2
- 1998
- 1
- 1999
- 1
- 2002
- 1
- 2008
- 1
- 2012
- 1
- 2013
- 1
- 2014
- 1
- 2016
- 1
- 系统测试
- 1
- NOIP 提高组
- 1