ACM之大数模板整理

目录:

      • 一.c++版本
        • 1.大数运算
        • 2.大数进制转换
        • 3.卡特兰数
      • 二.java大数

一.c++版本

1.大数运算

typedef long long ll;
const ll m=1e8;//大数数组每个元素为8位
struct Bigint{
	ll s[50];int l;//l为长度
	void print(){
		printf("%lld",s[l]);
		for(int i=l-1;i>=0;i--)printf("%08lld",s[i]);
	}
	void read(ll x){//将整数x存入高精度数组
		l=-1;memset(s,0,sizeof(s));
		do{
			s[++l]=x%m;
			x/=m;
		}while(x);
	}
}ans;
Bigint operator + (Bigint a,Bigint b){//大数加
	ll d=0;
	a.l=max(a.l,b.l);
	for(int i=0;i<=a.l;i++){
		a.s[i]+=d+b.s[i];
		d=a.s[i]/m;a.s[i]%=m;
	}
	if(d)a.s[++a.l]=d;
	return a;
}
Bigint operator - (Bigint a,Bigint b){//大数减
	ll d=0;
	for(int i=0;i<=a.l;i++){
		a.s[i]-=d;
		if(a.s[i]<b.s[i])a.s[i]+=m,d=1;
		else d=0;
		a.s[i]-=b.s[i];
	}
	while(a.l&&!a.s[a.l])a.l--;
	return a;
}
Bigint operator * (int b,Bigint a){//int与大数乘(顺序不能换)
	ll d=0;
	for(int i=0;i<=a.l;i++){
		d+=a.s[i]*b;a.s[i]=d%m;
		d/=m;
	}
	while(d){
		a.s[++a.l]=d%m;
		d/=m;
	}
	return a;
}
Bigint operator / (Bigint a,int b){//大数与int除(顺序不能变)
	ll d=0;
	for(int i=a.l;i>=0;i--){
		d*=m;d+=a.s[i];
		a.s[i]=d/b;d%=b;
	}
	while(a.l&&!a.s[a.l])a.l--;
	return a;
}
Bigint operator * (Bigint a,Bigint b){//大数与大数乘
	Bigint c;memset(c.s,0,sizeof(c.s));
	for(int i=0;i<=a.l;i++){
		for(int j=0;j<=b.l;j++){
			c.s[i+j]+=a.s[i]*b.s[j];
			if(c.s[i+j]>m){
				c.s[i+j+1]+=c.s[i+j]/m;
				c.s[i+j]%=m;
			}
		}
	}
	c.l=a.l+b.l+10;
	while(!c.s[c.l]&&c.l)c.l--;
	while(c.s[c.l]>m){
		c.s[c.l+1]+=c.s[c.l]/m;
		c.s[c.l++]%=m;
	}
	return c;
}
main:
ans.read(v)、ans.read(24)、ans=ans/24(ans/=24不可用)、ans=23*ans(ans*=23不可用);

2.大数进制转换

const int maxn=5000;
int t,m,n;
string str;
char hash1[maxn];
int hash2[maxn];
void init()//制定的大小规则(36进制内的)
{
    char ch;
    for(int i=0;i<36;i++){
        if(i<10)ch=i+'0';
        else ch='A'+i-10;
        //else ch='a'+i-10;
        hash1[i]=ch;
        hash2[ch]=i;
    }
}
string change(int m,int n,string str)//将str由m进制转为n进制
{
    bool flag;
    string ans="";
    int temp,quo,rem;
    while(true)
    {
        int len=str.length();
        flag=false;
        rem=0;
        string div="";
        for(int i=0;i<len;i++){
            temp=rem*m+hash2[str[i]];
            quo=temp/n;
            rem=temp%n;
            if(flag){
                div+=hash1[quo];
            }
            else {
                if(quo!=0){
                    flag=true;
                    div+=hash1[quo];
                }
            }
        }
        ans=hash1[rem]+ans;
        str=div;
        if(flag==false)break;
    }
    return ans;
}
int main()
{
    init();
    cin>>m>>n>>str;
    string ans=change(m,n,str);
    cout<<ans<<'\n';
    return 0;
}

3.卡特兰数

C n = ( 4 n − 2 ) C n − 1 n + 1 C n = C ( 2 n , n ) ( n + 1 ) ( n = 0 , 1 , 2 , . . . ) C n = C ( 2 n , n ) − C ( 2 n , n − 1 ) ( n = 0 , 1 , 2 , . . . ) C_n=\frac{(4n-2)C_{n-1}}{n+1}\\C_n=\frac {C(2n,n)}{(n+1) }(n=0,1,2,...)\\ C_n=C(2n,n)-C(2n,n-1)(n=0,1,2,...) Cn=n+1(4n2)Cn1Cn=(n+1)C(2n,n)(n=0,1,2,...)Cn=C(2n,n)C(2n,n1)(n=0,1,2,...)

35以内用公式一可以推出来,不会爆long long,100以内:

int a[101][101];//可以把a[i]看成第i个卡特兰数,需要倒序输出
int b[101];//b[i]表示第i个卡特兰数的长度;
void catalan() //求卡特兰数
{
    int i, j, len, carry, temp;
    a[1][0] = b[1] = 1;
    len = 1;
    for(i = 2; i <= 100; i++)
    {
        for(j = 0; j < len; j++) //乘法
        a[i][j] = a[i-1][j]*(4*(i-1)+2);
        carry = 0;
        for(j = 0; j < len; j++) //处理相乘结果
        {
            temp = a[i][j] + carry;
            a[i][j] = temp % 10;
            carry = temp / 10;
        }
        while(carry) //进位处理
        {
            a[i][len++] = carry % 10;
            carry /= 10;
        }
        carry = 0;
        for(j = len-1; j >= 0; j--) //除法
        {
            temp = carry*10 + a[i][j];
            a[i][j] = temp/(i+1);
            carry = temp%(i+1);
        }
        while(!a[i][len-1]) //高位零处理
        len --;
        b[i] = len;
    }
}
int main()
{
    catalan();
    for(int i=1;i<=100;i++){
        for(int j=b[i]-1;j>=0;j--)
        cout<<a[i][j];
        cout<<'\n';
    }
    return 0;
}

二.java大数

import java.math.*;
import java.util.*;
public class Main {
    //BigDecimal是针对浮点型的操作
    //赋值:(1) BigInteger a = new BigInteger(string)/cin.nextBigInteger()
    //(2)int t=cin.nextInt(); BigInteger a=BigInteger.valueOf(t);
	public static void main(String[] args) {
         Scanner cin = Scanner(System.in);
         while(cin.hasNest())//等价于!=EOF
         BigInteger a=cin.nextBigInteger();
         BigInteger b=cin.nextBigInteger();
         int n=cin.nextInt();
         //算术运算
		 BigInteger a.add(b);//加法
		 BigInteger a.subtract(b);//减法
		 BigInteger a.divide(b);//除法
		 BigInteger a.multiply(b);//乘法
         BigInteger a.negate()//返回-a
		 BigInteger a.remainder(b);//取余数 a%b 可能为负
         BigInteger a.mod(b)  //返回其值为(a mod b)的BigInteger(与%不同,其值永远为正,下同)
         BigInteger a.modInverse(b)   //返回其值为((a^(-1)) mod b)的BigInteger
         BigInteger a.modPow(BigInteger c,BigInteger b)//返回其值为((a^c) mod b)的BigInteger(c可以为负)
	  	 boolean a.compareTo(b);//比较两个数字的大小,小于返回-1,大于返回1,等于0的时候返回0
		 //逻辑运算和位运算
         BigInteger a.not(); //对a取反
		 BigInteger a.and(b); //a和b按位与
		 BigInteger a.or(b); //a和b按位或
		 BigInteger a.xor(b); //a和b异或
         BigInteger a.shiftLeft(n); //左移n位 n>=0
		 BigInteger a.shiftRight(n); //右移n位 n>=0
         //进制转换
         (1)String str = Integer.toString(num,base);//10进制数num转base进制(x<=35),默认小写字母
         (2)String str.toUpperCase(); //将小写字母转成大写
         (3)int num=Integer.parseInt(num,base);//把num当作base进制,转成10进制的int num开始为字符串
         (4)n=Integer.valueOf(str,x) //将x进制的字符串转换成10进制
		 (1)String a.toString(n); //将a转换成n进制的字符串(进制的转换) 
         (2)String ans=new BigInteger(str,x).toString(y);//x进制转y进制
         //二进制运算
		 boolean a.testBit(n); //((a & (1 << n)) != 0)	
         BigInteger a.setBit(n) //(a | (1 << n))
         BigInteger a.clearBit(n) //(a & ~(1 << n))
         BigInteger flipBit(n) //(a ^ (1 << n))
         //数学函数
         BigInteger a.pow(b); //a的b次幂的运算
		 BigInteger a.min(b); //返回较小的数
		 BigInteger a.max(b); //返回较大的数
         BigInteger a.gcd(b); //返回a和b的最大公约数
         BigInteger a.abs();  //返回a的绝对值
         int a.hashCode(); //返回a的哈希码
         boolean a.isProbablePrime(n); //如果a可能为素数,则返回true,如果它一定为合数,则返回false
        //(n为调用方允许的不确定性的度量,如果该调用返回 true,则a是素数的概率超出 (1 - (1/2)^n),此方法的执行时间与此参数的值是成比例的)
         BigInteger a.nextProbablePrime(); //返回大于a的可能为素数的第一个整数
	}
}

你可能感兴趣的:(模板,大数)