高精度开跟模板

实质:二分+高精度乘法

  1 struct node {
  2     typedef ll INT;
  3     static const INT S=100000000;
  4     static const int S_n=9;
  5     static const int SIZE=305;
  6     INT a[SIZE]; int len, tag;
  7     node() { len=1; CC(a, 0); }
  8     node(char *s) { len=1; CC(a, 0); *this=s; }
  9     node(INT x) { len=1; CC(a, 0); *this=x; }
 10     void cln() { memset(a, 0, sizeof(INT)*(len+1)); len=1; tag=0; }
 11     void fix() { while(len>1 && !a[len]) --len; }
 12     void M(node &a, node &b, node &c) {
 13         if(b.tag) { b.tag=0; P(a, b, c); b.tag=1; return; }
 14         if(a.tag) { a.tag=0; P(a, b, c); a.tag=1; c.tag=1; return; }
 15         c.cln();
 16         int flag=0, i=1;
 17         node *x=&a, *y=&b;
 18         if(a<b) flag=1, swap(x, y);
 19         for(; i<=x->len; ++i) {
 20             c.a[i]+=x->a[i]-y->a[i];
 21             if(c.a[i]<0) c.a[i]+=S, --c.a[i+1];
 22         }
 23         c.len=i;
 24         c.fix();
 25         c.tag=flag;
 26     }
 27     void P(node &a, node &b, node &c) {
 28         if(b.tag) { b.tag=0; M(a, b, c); b.tag=1; return; }
 29         if(a.tag) { a.tag=0; M(b, a, c); a.tag=1; return; }
 30         c.cln();
 31         int i=1, l=max(a.len, b.len); INT k=0;
 32         for(; i<=l || k; ++i) {
 33             c.a[i]=a.a[i]+b.a[i]+k;
 34             k=c.a[i]/S;
 35             if(c.a[i]>=S) c.a[i]%=S;
 36         }
 37         c.len=i;
 38         c.fix();
 39     }
 40     void T(node &a, node &b, node &c) {
 41         c.cln();
 42         for1(i, 1, a.len) for1(j, 1, b.len) {
 43             int pos=i+j-1;
 44             c.a[pos]+=a.a[i]*b.a[j];
 45             c.a[pos+1]+=c.a[pos]/S;
 46             c.a[pos]%=S;
 47         }
 48         c.len=a.len+b.len;
 49         c.fix();
 50         c.tag=a.tag^b.tag;
 51         if(c.a[1]==0 && c.len==1) c.tag=0;
 52     }
 53     void D(node &a, INT b, node &c) {
 54         c.cln(); INT t=0;
 55         for(int i=len; i; --i) {
 56             c.a[i]=(a.a[i]+t)/b;
 57             t=((a.a[i]+t)%b)*S;
 58         }
 59         c.len=len;
 60         c.fix();
 61     }
 62     void D(node &a, node &b, node &c) {
 63         c.cln();
 64         node l, r=a, mid, TP, ONE=(INT)1;
 65         while(l<=r) {
 66             P(l, r, TP); D(TP, 2, mid);
 67             T(mid, b, TP);
 68             if(TP<=a) P(mid, ONE, l);
 69             else M(mid, ONE, r);
 70         }
 71         M(l, ONE, c);
 72         c.tag=a.tag^b.tag;
 73         if(c.a[1]==0 && c.len==1) c.tag=0;
 74     }
 75     node sqrt() {
 76         node l, r=*this, mid, TP, ONE=(INT)1;
 77         while(l<=r) {
 78             P(l, r, TP); D(TP, 2, mid);
 79             T(mid, mid, TP);
 80             if(TP<=*this) P(mid, ONE, l);
 81             else M(mid, ONE, r);
 82         }
 83         M(l, ONE, TP);
 84         return TP;
 85     }
 86     bool operator<(node &b) {
 87         if(b.tag && !tag) return 0;
 88         if(!b.tag && tag) return 1;
 89         if(b.tag && tag) { tag=b.tag=0; bool ret=b<*this; tag=b.tag=1; return ret; }
 90         if(len!=b.len) return len<b.len;
 91         for3(i, len, 1) if(a[i]<b.a[i]) return true; else if(a[i]>b.a[i]) return false; //这里一定要注意
 92         return false;
 93     }
 94     node& operator= (INT b) {
 95         cln();
 96         len=0;
 97         if(b==0) { len=1; return *this; }
 98         if(b<0) tag=1, b=-b;
 99         while(b) { a[++len]=b%S; b/=S; }
100         return *this;
101     }
102     node& operator= (char *s) {
103         cln();
104         if(s[0]==‘-‘) tag=1, ++s;
105         len=0; int l=strlen(s), t=0, k=1;
106         for3(i, l-1, 0) {
107             t=t+(s[i]-‘0‘)*k;
108             k*=10;
109             if(k>=S) a[++len]=t%S, t=0, k=1;
110         }
111         if(k!=1) a[++len]=t%S;
112         return *this;
113     }
114     node& operator= (const node &x) {
115         cln();
116         memcpy(a, x.a, sizeof(INT)*(x.len+1));
117         len=x.len, tag=x.tag;
118         return *this;
119     }
120     node operator+ (node x) { node c; P(*this, x, c); return c; }
121     node operator- (node x) { node c; M(*this, x, c); return c; }
122     node operator* (node x) { node c; T(*this, x, c); return c; }
123     node operator/ (node x) { node c; D(*this, x, c); return c; }
124     node operator/ (INT x) { node c; D(*this, x, c); return c; }
125     node& operator+= (node x) { node c; P(*this, x, c); return *this=c; }
126     node& operator-= (node x) { node c; M(*this, x, c); return *this=c; }
127     node& operator*= (node x) { node c; T(*this, x, c); return *this=c; }
128     node& operator/= (node x) { node c; D(*this, x, c); return *this=c; }
129     node& operator/= (INT x) { node c; D(*this, x, c); return *this=c; }
130     node& operator++ () { return *this+=1; }
131     node operator++ (int) { node ret=*this; ++*this; return ret; }
132     node& operator-- () { return *this-=1; }
133     node operator-- (int) { node ret=*this; --*this; return ret; }
134     bool operator> (node &x) { return x<*this; }
135     bool operator== (node &x) { return x<=*this&&x>=*this; }
136     bool operator<= (node &x) { return !(x<*this); }
137     bool operator>= (node &x) { return !(x>*this); }
138     void P() {
139         if(tag) putchar(‘-‘);
140         printf("%d", (int)a[len]);
141         char od[8]; od[0]=‘%‘; od[1]=‘0‘;
142         sprintf(od+2, "%d", S_n-1);
143         int l=strlen(od); od[l]=‘d‘; od[l+1]=‘\0‘;
144         for3(i, len-1, 1) printf(od, (int)a[i]);
145     }
146 };

原文地址:https://www.cnblogs.com/adelalove/p/9806990.html

时间: 2024-10-18 05:53:20

高精度开跟模板的相关文章

神奇的开根号模板

在codevs里发现的一份高精度开根号模板. int l,last; int work(int o,char *O,int I) { char c,*D=O; if(o>0) { for(l=0;D[l];D[l++]-=10) { D[l++]-=120; D[l]-=110; while(!work(0,O,l)) D[l]+=20; last=((D[l]+1032)/20); } //putchar(10); } else { c=o+(D[I]+82)%10-(I>l/2)*(D[I

【BZOJ1213】高精度开根

python是坠吼的! 原题: 不贴原题,就是高精度开根,结果向下取整 首先二分答案,高精度嘛--python即可 二分右端点设为n会T掉,需要先倍增一个r,while(r **m <= n)  r *= 2 然后T掉了,代码如下,亮点自寻 1 m, n = input(), input() 2 l, r = 0, n 3 while r ** m < n: 4 r *= 2 5 6 while(l + 1 < r): 7 md = (l + r) >> 1 8 if(md

【HNOI2004】【BZOJ1213】高精度开根

Description 晓华所在的工作组正在编写一套高精度科学计算的软件,一些简单的部分如高精度加减法.乘除法早已写完了,现在就剩下晓华所负责的部分:实数的高精度开m次根.因为一个有理数开根之后可能得到一个无理数,所以这项工作是有较大难度的.现在要做的只是这项工作的第一步:只对自然数进行开整数次根,求出它的一个非负根,并且不考虑结果的小数部分,只要求把结果截断取整即可.程序需要根据给定的输入,包括需要开根的次数,以及被开根的整数:计算出它的非负根取整后的结果. Input 共有两行,每行都有一个

大数高精度运算(模板)

前言:高精度运算.是指參与运算的数(加数.减数,因子--)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算. 模板:包含大数加减乘除.大数与int数的乘法,模板能够不断扩充. 代码: /* 所有亲測可用,可是不能用于负数的运算,仅仅能对正数进行大数运算 */ const int ten[4]= {1,10,100,1000}; const int maxl = 300; struct BigNumber { int d[maxl]; char s[maxl]; BigNumber(co

高精度乘法FFT 模板

渣模板,不知为何常数还挺大.. CODE: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 200010 #define PI 3.1415926535897932384626 using namespace std; struct Complex{ double real,imag

BZOJ 1213 HNOI2004 高精度开根 二分+高(Py)精(thon)度

题目大意:求n^(1/m) 一大早水个Python- - 直接开根尼玛过不去- - 需要二分- - m,n=int(raw_input()),int(raw_input()) l,r=0,1 while r**m<=n: l=r;r=r*2 while l+1<r: mid=(l+r)//2 if mid**m<=n: l=mid else: r=mid if r**m<=n: print r else: print l

【高精度】【模板】高精度模板

没有什么好说的,照着模板写就是了,稍微用了点手段,支持负数的减法了 1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<algorithm> 5 #include<vector> 6 #include<iostream> 7 using namespace std; 8 const int maxn=510; 9 struct bigint 10 {

PAT A1024题解——高精度大数相加模板

#include<stdio.h>#include<string.h>#include<algorithm>typedef long long ll;using namespace std;struct bign{    int d[1000];    int len;    bign(){        memset(d,0,sizeof(d));        len = 0;    }}; bign change(char str[]){     //将整数转换为

高精度乘除法模板(AcWing.793 794)

高精度乘法一般都是由一个大数乘以一个可以由int存放的整数类型. #include <iostream> #include <vector> using namespace std; vector<int> mul(vector<int> &a,int b){ int t = 0; vector<int> c; for (int i=0;i<a.size()||t; i++){ //判断程序终止的条件有两个一个是i小于数组长度另一个