• 个人简介

    高精度运算 *

    #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