#include<queue>\#include<queue>#include<queue>
#include<stdio.h>\#include<stdio.h>#include<stdio.h>
#include<string.h>\#include<string.h>#include<string.h>
#include<algorithm>\#include<algorithm>#include<algorithm>
#define N 4010\#define\ N\ 4010#define N 4010
using namespace std;using\ namespace\ std;using namespace std;
struct V{ int x,y,d; } z;struct\ V\{\ int\ x,y,d;\ \}\ z;struct V{ int x,y,d; } z;
char A[N],B[N]; int n,m,l[N],f[N][N]; queue<V> q;char\ A[N],B[N];\ int\ n,m,l[N],f[N][N];\ queue<V>\ q;char A[N],B[N]; int n,m,l[N],f[N][N]; queue<V> q;
namespace SAM{namespace\ SAM\{namespace SAM{
int s[N][26],mx[N],f[N],cnt=1,lst=1;\quad int\ s[N][26],mx[N],f[N],cnt=1,lst=1;int s[N][26],mx[N],f[N],cnt=1,lst=1;
inline int extend(int c){\quad inline\ int\ extend(int\ c)\{inline int extend(int c){
int p=lst,np=lst=++cnt,q,nq;\quad \quad int\ p=lst,np=lst=++cnt,q,nq;int p=lst,np=lst=++cnt,q,nq;
mx[np]=mx[p]+1;\quad \quad mx[np]=mx[p]+1;mx[np]=mx[p]+1;
for(;p&&!s[p][c];p=f[p]) s[p][c]=np;\quad \quad for(;p\&\&!s[p][c];p=f[p])\ s[p][c]=np;for(;p&&!s[p][c];p=f[p]) s[p][c]=np;
if(!p) return f[np]=1;\quad \quad if(!p)\ return\ f[np]=1;if(!p) return f[np]=1;
q=s[p][c];\quad \quad q=s[p][c];q=s[p][c];
if(mx[q]==mx[p]+1) f[np]=q;\quad \quad if(mx[q]==mx[p]+1)\ f[np]=q;if(mx[q]==mx[p]+1) f[np]=q;
else{\quad \quad else\{else{
nq=++cnt;\quad \quad \quad nq=++cnt;nq=++cnt;
mx[nq]=mx[p]+1;\quad \quad \quad mx[nq]=mx[p]+1;mx[nq]=mx[p]+1;
f[nq]=f[q]; f[q]=f[np]=nq;\quad \quad \quad f[nq]=f[q];\ f[q]=f[np]=nq;f[nq]=f[q]; f[q]=f[np]=nq;
memcpy(s[nq],s[q],26<<2);\quad \quad \quad memcpy(s[nq],s[q],26<<2);memcpy(s[nq],s[q],26<<2);
for(;p&&s[p][c]==q;p=f[p]) s[p][c]=nq;\quad \quad \quad for(;p\&\&s[p][c]==q;p=f[p])\ s[p][c]=nq;for(;p&&s[p][c]==q;p=f[p]) s[p][c]=nq;
}\quad \quad \}}
}\quad \}}
inline void match(){\quad inline\ void\ match()\{inline void match(){
for(int x=1,i=1,c=0;i<=n;++i){\quad \quad for(int\ x=1,i=1,c=0;i<=n;++i)\{for(int x=1,i=1,c=0;i<=n;++i){
for(;x>1 && !s[x][A[i]−′a′];x=f[x]);\quad \quad \quad for(;x>1\ \&\&\ !s[x][A[i]-'a'];x=f[x]);for(;x>1 && !s[x][A[i]−′a′];x=f[x]);
c=mx[x];\quad \quad \quad c=mx[x];c=mx[x];
if(!s[x][A[i]−′a′]) l[i]=0; else{\quad \quad \quad if(!s[x][A[i]-'a'])\ l[i]=0;\ else\{if(!s[x][A[i]−′a′]) l[i]=0; else{
x=s[x][A[i]−′a′]; l[i]=++c;\quad \quad \quad \quad x=s[x][A[i]-'a'];\ l[i]=++c;x=s[x][A[i]−′a′]; l[i]=++c;
}\quad \quad \quad \}}
}\quad \quad \}}
}\quad \}}
}\}}
namespace AAM{namespace\ AAM\{namespace AAM{
int s[N][26];\quad int\ s[N][26];int s[N][26];
inline void build(){\quad inline\ void\ build()\{inline void build(){
for(int i=1;i<=n;++i)\quad \quad for(int\ i=1;i<=n;++i)for(int i=1;i<=n;++i)
for(int j=i−1;;−−j){\quad \quad \quad for(int\ j=i-1;;--j)\{for(int j=i−1;;−−j){
s[j][A[i]−′a′]=i;\quad \quad \quad \quad s[j][A[i]-'a']=i;s[j][A[i]−′a′]=i;
if(A[j]==A[i] ∣∣ !j) break;\quad \quad \quad \quad if(A[j]==A[i]\ ||\ !j)\ break;if(A[j]==A[i] ∣∣ !j) break;
}\quad \quad \quad \}}
}\quad \}}
}\}}
namespace BAM{namespace\ BAM\{namespace BAM{
int s[N][26];\quad int\ s[N][26];int s[N][26];
inline void build(){\quad inline\ void\ build()\{inline void build(){
for(int i=1;i<=m;++i)\quad \quad for(int\ i=1;i<=m;++i)for(int i=1;i<=m;++i)
for(int j=i−1;;−−j){\quad \quad \quad for(int\ j=i-1;;--j)\{for(int j=i−1;;−−j){
s[j][B[i]−′a′]=i;\quad \quad \quad \quad s[j][B[i]-'a']=i;s[j][B[i]−′a′]=i;
if(B[j]==B[i] ∣∣ !j) break;\quad \quad \quad \quad if(B[j]==B[i]\ ||\ !j)\ break;if(B[j]==B[i] ∣∣ !j) break;
}\quad \quad \quad \}}
}\quad \}}
}\}}
inline void dfs(int x,int y,int d){inline\ void\ dfs(int\ x,int\ y,int\ d)\{inline void dfs(int x,int y,int d){
for(int i=0;i<26;++i)\quad for(int\ i=0;i<26;++i)for(int i=0;i<26;++i)
if(AAM::s[x][i]&&!SAM::s[y][i]){\quad \quad if(AAM::s[x][i]\&\&!SAM::s[y][i])\{if(AAM::s[x][i]&&!SAM::s[y][i]){
∗l=min(∗l,d+1); return;\quad \quad \quad *l=min(*l,d+1);\ return;∗l=min(∗l,d+1); return;
}\quad \quad \}}
for(int i=0;i<26;++i)\quad for(int\ i=0;i<26;++i)for(int i=0;i<26;++i)
if(AAM::s[x][i]&&SAM::s[y][i])\quad \quad if(AAM::s[x][i]\&\&SAM::s[y][i])if(AAM::s[x][i]&&SAM::s[y][i])
dfs(AAM::s[x][i],SAM::s[y][i],d+1);\quad \quad \quad dfs(AAM::s[x][i],SAM::s[y][i],d+1);dfs(AAM::s[x][i],SAM::s[y][i],d+1);
}\}}
int main(){int\ main()\{int main(){
scanf("%s%s",A+1,B+1);\quad scanf("\%s\%s",A+1,B+1);scanf("%s%s",A+1,B+1);
n=strlen(A+1); m=strlen(B+1);\quad n=strlen(A+1);\ m=strlen(B+1);n=strlen(A+1); m=strlen(B+1);
for(int i=1;i<=n;++i) SAM::extend(B[i]−′a′);\quad for(int\ i=1;i<=n;++i)\ SAM::extend(B[i]-'a');for(int i=1;i<=n;++i) SAM::extend(B[i]−′a′);
SAM::match();\quad SAM::match();SAM::match();
AAM::build(); BAM::build();\quad AAM::build();\ BAM::build();AAM::build(); BAM::build();
∗l=n; for(int i=1;i<=n;++i) if(l[i]<i) ∗l=min(∗l,l[i]+1);\quad *l=n;\ for(int\ i=1;i<=n;++i)\ if(l[i]<i)\ *l=min(*l,l[i]+1);∗l=n; for(int i=1;i<=n;++i) if(l[i]<i) ∗l=min(∗l,l[i]+1);
printf("%d\n",∗l); ∗l=n;\quad printf("\%d\backslash n",*l);\ *l=n;printf("%d\n",∗l); ∗l=n;
for(int i=1;i<=n;++i){\quad for(int\ i=1;i<=n;++i)\{for(int i=1;i<=n;++i){
int x=0;\quad \quad int\ x=0;int x=0;
for(int j=i;j<=n;++j){\quad \quad for(int\ j=i;j<=n;++j)\{for(int j=i;j<=n;++j){
x=BAM::s[x][A[j]−′a′];\quad \quad \quad x=BAM::s[x][A[j]-'a'];x=BAM::s[x][A[j]−′a′];
if(!x){ ∗l=min(∗l,j−i+1); break; }\quad \quad \quad if(!x)\{\ *l=min(*l,j-i+1);\ break;\ \}if(!x){ ∗l=min(∗l,j−i+1); break; }
}\quad \quad \}}
}\quad \}}
printf("%d\n",∗l); dfs(0,1,0);\quad printf("\%d\backslash n",*l);\ dfs(0,1,0);printf("%d\n",∗l); dfs(0,1,0);
printf("%d\n",∗l); ∗l=n;\quad printf("\%d\backslash n",*l);\ *l=n;printf("%d\n",∗l); ∗l=n;
q.push((V){0,0,0});\quad q.push((V)\{0,0,0\});q.push((V){0,0,0});
for(int x,y,d;!q.empty();q.pop()){\quad for(int\ x,y,d;!q.empty();q.pop())\{for(int x,y,d;!q.empty();q.pop()){
z=q.front();\quad \quad z=q.front();z=q.front();
for(int i=0;i<26;++i)if(x=AAM::s[z.x][i]){\quad \quad for(int\ i=0;i<26;++i)if(x=AAM::s[z.x][i])\{for(int i=0;i<26;++i)if(x=AAM::s[z.x][i]){
if(!(y=BAM::s[z.y][i])){ printf("%d\n",z.d+1); return 0; }\quad \quad \quad if(!(y=BAM::s[z.y][i]))\{\ printf("\%d\backslash n",z.d+1);\ return\ 0;\ \}if(!(y=BAM::s[z.y][i])){ printf("%d\n",z.d+1); return 0; }
else if(!f[x][y]){ f[x][y]=1; q.push((V){x,y,z.d+1}); }\quad \quad \quad else\ if(!f[x][y])\{\ f[x][y]=1;\ q.push((V)\{x,y,z.d+1\});\ \}else if(!f[x][y]){ f[x][y]=1; q.push((V){x,y,z.d+1}); }
}\quad \quad \}}
}\quad \}}
}\}}
#include <cstdio>\#include\ <cstdio>#include <cstdio>
#include <iostream>\#include\ <iostream>#include <iostream>
#include <algorithm>\#include\ <algorithm>#include <algorithm>
#include <cstring>\#include\ <cstring>#include <cstring>
#include <cstring>\#include\ <cstring>#include <cstring>
#include <cmath>\#include\ <cmath>#include <cmath>
typedef long long ll;typedef\ long\ long\ ll;typedef long long ll;
int powermod(int a, int exp, int moder)int\ powermod(int\ a,\ int\ exp,\ int\ moder)int powermod(int a, int exp, int moder)
{\{{
int ret = 1;\ \ \ \ int\ ret\ =\ 1; int ret = 1;
for (; exp; exp >>= 1)\ \ \ \ for\ (;\ exp;\ exp\ >>=\ 1) for (; exp; exp >>= 1)
{\ \ \ \ \{ {
if (exp & 1)\ \ \ \ \ \ \ \ if\ (exp\ \&\ 1) if (exp & 1)
{\ \ \ \ \ \ \ \ \{ {
ret = 1ll ∗ ret ∗ a % moder;\ \ \ \ \ \ \ \ \ \ \ \ ret\ =\ 1ll\ *\ ret\ *\ a\ \%\ moder; ret = 1ll ∗ ret ∗ a % moder;
}\ \ \ \ \ \ \ \ \} }
a = 1ll ∗ a ∗ a % moder;\ \ \ \ \ \ \ \ a\ =\ 1ll\ *\ a\ *\ a\ \%\ moder; a = 1ll ∗ a ∗ a % moder;
}\ \ \ \ \} }
return ret;\ \ \ \ return\ ret; return ret;
}\}}
void addminus(int ∗a, int ∗b, int &lengtha, int &lengthb, int type)void\ addminus(int\ *a,\ int\ *b,\ int\ \&lengtha,\ int\ \&lengthb,\ int\ type)void addminus(int ∗a, int ∗b, int &lengtha, int &lengthb, int type)
{\{{
int length = std::max(lengtha, lengthb);\ \ \ \ int\ length\ =\ std::max(lengtha,\ lengthb); int length = std::max(lengtha, lengthb);
for (int i = 0; i < length; ++i)\ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ length;\ ++i) for (int i = 0; i < length; ++i)
{\ \ \ \ \{ {
a[i] += type == 1 ? b[i] : −b[i];\ \ \ \ \ \ \ \ a[i]\ +=\ type\ ==\ 1\ ?\ b[i]\ :\ -b[i]; a[i] += type == 1 ? b[i] : −b[i];
a[i] >= 10 ? (a[i] −= 10, ++a[i + 1]) : a[i] < 0 ? (a[i] += 10, −−a[i + 1]) : 0;\ \ \ \ \ \ \ \ a[i]\ >=\ 10\ ?\ (a[i]\ -=\ 10,\ ++a[i\ +\ 1])\ :\ a[i]\ <\ 0\ ?\ (a[i]\ +=\ 10,\ --a[i\ +\ 1])\ :\ 0; a[i] >= 10 ? (a[i] −= 10, ++a[i + 1]) : a[i] < 0 ? (a[i] += 10, −−a[i + 1]) : 0;
}\ \ \ \ \} }
for (lengtha = length + 1; lengtha && !a[lengtha − 1]; −−lengtha) ;\ \ \ \ for\ (lengtha\ =\ length\ +\ 1;\ lengtha\ \&\&\ !a[lengtha\ -\ 1];\ --lengtha)\ ; for (lengtha = length + 1; lengtha && !a[lengtha − 1]; −−lengtha) ;
}\}}
struct BigIntegerstruct\ BigIntegerstruct BigInteger
{\{{
const static int MAXN = 19;\ \ \ \ const\ static\ int\ MAXN\ =\ 19; const static int MAXN = 19;
const static int MOD = (119 << 23) + 1; // 998244353\ \ \ \ const\ static\ int\ MOD\ =\ (119\ <<\ 23)\ +\ 1;\ \ \ //\ \ 998244353 const static int MOD = (119 << 23) + 1; // 998244353
const static int root = 3;\ \ \ \ const\ static\ int\ root\ =\ 3; const static int root = 3;
const static int invroot = 332748118;\ \ \ \ const\ static\ int\ invroot\ =\ 332748118; const static int invroot = 332748118;
int a[1 << MAXN];\ \ \ \ int\ a[1\ <<\ MAXN]; int a[1 << MAXN];
int length, sig;\ \ \ \ int\ length,\ sig; int length, sig;
BigInteger()\ \ \ \ BigInteger() BigInteger()
{\ \ \ \ \{ {
memset(a, 0, sizeof(a));\ \ \ \ \ \ \ \ memset(a,\ 0,\ sizeof(a)); memset(a, 0, sizeof(a));
length = sig = 0;\ \ \ \ \ \ \ \ length\ =\ sig\ =\ 0; length = sig = 0;
}\ \ \ \ \} }
void clear()\ \ \ \ void\ clear() void clear()
{\ \ \ \ \{ {
memset(a, 0, sizeof(int) ∗ length);\ \ \ \ \ \ \ \ memset(a,\ 0,\ sizeof(int)\ *\ length); memset(a, 0, sizeof(int) ∗ length);
length = sig = 0;\ \ \ \ \ \ \ \ length\ =\ sig\ =\ 0; length = sig = 0;
}\ \ \ \ \} }
void read()\ \ \ \ void\ read() void read()
{\ \ \ \ \{ {
clear();\ \ \ \ \ \ \ \ clear(); clear();
char ch = getchar();\ \ \ \ \ \ \ \ char\ ch\ =\ getchar(); char ch = getchar();
for (; (ch < ′0′ ∣∣ ch > ′9′) && ch != ′−′; ch = getchar()) ;\ \ \ \ \ \ \ \ for\ (;\ (ch\ <\ '0'\ ||\ ch\ >\ '9')\ \&\&\ ch\ !=\ '-';\ ch\ =\ getchar())\ ; for (; (ch < ′0′ ∣∣ ch > ′9′) && ch != ′−′; ch = getchar()) ;
ch == ′−′ ? (sig = −1, ch = getchar()) : sig = 1;\ \ \ \ \ \ \ \ ch\ ==\ '-'\ ?\ (sig\ =\ -1,\ ch\ =\ getchar())\ :\ sig\ =\ 1; ch == ′−′ ? (sig = −1, ch = getchar()) : sig = 1;
for (; ch >= ′0′ && ch <= ′9′; ch = getchar())\ \ \ \ \ \ \ \ for\ (;\ ch\ >=\ '0'\ \&\&\ ch\ <=\ '9';\ ch\ =\ getchar()) for (; ch >= ′0′ && ch <= ′9′; ch = getchar())
{\ \ \ \ \ \ \ \ \{ {
a[length ++] = ch − ′0′;\ \ \ \ \ \ \ \ \ \ \ \ a[length\ ++]\ =\ ch\ -\ '0'; a[length ++] = ch − ′0′;
}\ \ \ \ \ \ \ \ \} }
std::reverse(a, a + length);\ \ \ \ \ \ \ \ std::reverse(a,\ a\ +\ length); std::reverse(a, a + length);
for (; length && !a[length − 1]; −−length) ;\ \ \ \ \ \ \ \ for\ (;\ length\ \&\&\ !a[length\ -\ 1];\ --length)\ ; for (; length && !a[length − 1]; −−length) ;
sig = length ? sig : 0;\ \ \ \ \ \ \ \ sig\ =\ length\ ?\ sig\ :\ 0; sig = length ? sig : 0;
}\ \ \ \ \} }
void write()\ \ \ \ void\ write() void write()
{\ \ \ \ \{ {
if (!sig)\ \ \ \ \ \ \ \ if\ (!sig) if (!sig)
{\ \ \ \ \ \ \ \ \{ {
return (void)putchar(′0′);\ \ \ \ \ \ \ \ \ \ \ \ return\ (void)putchar('0'); return (void)putchar(′0′);
}\ \ \ \ \ \ \ \ \} }
if (sig < 0)\ \ \ \ \ \ \ \ if\ (sig\ <\ 0) if (sig < 0)
{\ \ \ \ \ \ \ \ \{ {
putchar(′−′);\ \ \ \ \ \ \ \ \ \ \ \ putchar('-'); putchar(′−′);
}\ \ \ \ \ \ \ \ \} }
for (int i = length − 1; i >= 0; i−−)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ length\ -\ 1;\ i\ >=\ 0;\ i--) for (int i = length − 1; i >= 0; i−−)
{\ \ \ \ \ \ \ \ \{ {
putchar(a[i] + ′0′);\ \ \ \ \ \ \ \ \ \ \ \ putchar(a[i]\ +\ '0'); putchar(a[i] + ′0′);
}\ \ \ \ \ \ \ \ \} }
}\ \ \ \ \} }
template <typename T>\ \ \ \ template\ <typename\ T> template <typename T>
T tointeger()\ \ \ \ T\ tointeger() T tointeger()
{\ \ \ \ \{ {
T ret = 0;\ \ \ \ \ \ \ \ T\ ret\ =\ 0; T ret = 0;
for (int i = length − 1; i >= 0; ++i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ length\ -\ 1;\ i\ >=\ 0;\ ++i) for (int i = length − 1; i >= 0; ++i)
{\ \ \ \ \ \ \ \ \{ {
ret = ret ∗ 10 + a[i];\ \ \ \ \ \ \ \ \ \ \ \ ret\ =\ ret\ *\ 10\ +\ a[i]; ret = ret ∗ 10 + a[i];
}\ \ \ \ \ \ \ \ \} }
return ret ∗ sig;\ \ \ \ \ \ \ \ return\ ret\ *\ sig; return ret ∗ sig;
}\ \ \ \ \} }
bool equal(const BigInteger &p)\ \ \ \ bool\ equal(const\ BigInteger\ \&p) bool equal(const BigInteger &p)
{\ \ \ \ \{ {
if (sig != p.sig ∣∣ length != p.length)\ \ \ \ \ \ \ \ if\ (sig\ !=\ p.sig\ ||\ length\ !=\ p.length) if (sig != p.sig ∣∣ length != p.length)
{\ \ \ \ \ \ \ \ \{ {
return false;\ \ \ \ \ \ \ \ \ \ \ \ return\ false; return false;
}\ \ \ \ \ \ \ \ \} }
for (int i = 0; i < length; ++i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ length;\ ++i) for (int i = 0; i < length; ++i)
{\ \ \ \ \ \ \ \ \{ {
if (a[i] != p.a[i])\ \ \ \ \ \ \ \ \ \ \ \ if\ (a[i]\ !=\ p.a[i]) if (a[i] != p.a[i])
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
return false;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ false; return false;
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
}\ \ \ \ \ \ \ \ \} }
return true;\ \ \ \ \ \ \ \ return\ true; return true;
}\ \ \ \ \} }
bool greater(const BigInteger &p)\ \ \ \ bool\ greater(const\ BigInteger\ \&p) bool greater(const BigInteger &p)
{\ \ \ \ \{ {
if (sig != p.sig)\ \ \ \ \ \ \ \ if\ (sig\ !=\ p.sig) if (sig != p.sig)
{\ \ \ \ \ \ \ \ \{ {
return sig > p.sig;\ \ \ \ \ \ \ \ \ \ \ \ return\ sig\ >\ p.sig; return sig > p.sig;
}\ \ \ \ \ \ \ \ \} }
if (length != p.length)\ \ \ \ \ \ \ \ if\ (length\ !=\ p.length) if (length != p.length)
{\ \ \ \ \ \ \ \ \{ {
return length > p.length ∧ sig == −1;\ \ \ \ \ \ \ \ \ \ \ \ return\ length\ >\ p.length\ \wedge \ sig\ ==\ -1; return length > p.length ∧ sig == −1;
}\ \ \ \ \ \ \ \ \} }
for (int i = length − 1; i >= 0; −−i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ length\ -\ 1;\ i\ >=\ 0;\ --i) for (int i = length − 1; i >= 0; −−i)
{\ \ \ \ \ \ \ \ \{ {
if (a[i] > p.a[i])\ \ \ \ \ \ \ \ \ \ \ \ if\ (a[i]\ >\ p.a[i]) if (a[i] > p.a[i])
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
return sig > 0;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ sig\ >\ 0; return sig > 0;
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
else if (a[i] < p.a[i])\ \ \ \ \ \ \ \ \ \ \ \ else\ if\ (a[i]\ <\ p.a[i]) else if (a[i] < p.a[i])
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
return sig < 0;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ sig\ <\ 0; return sig < 0;
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
}\ \ \ \ \ \ \ \ \} }
return false;\ \ \ \ \ \ \ \ return\ false; return false;
}\ \ \ \ \} }
void leftshift(int dis)\ \ \ \ void\ leftshift(int\ dis) void leftshift(int dis)
{\ \ \ \ \{ {
for (int i = length + dis − 1; i >= dis; −−i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ length\ +\ dis\ -\ 1;\ i\ >=\ dis;\ --i) for (int i = length + dis − 1; i >= dis; −−i)
{\ \ \ \ \ \ \ \ \{ {
a[i] = a[i − dis];\ \ \ \ \ \ \ \ \ \ \ \ a[i]\ =\ a[i\ -\ dis]; a[i] = a[i − dis];
}\ \ \ \ \ \ \ \ \} }
memset(a, 0, sizeof(int) ∗ dis);\ \ \ \ \ \ \ \ memset(a,\ 0,\ sizeof(int)\ *\ dis); memset(a, 0, sizeof(int) ∗ dis);
length += dis;\ \ \ \ \ \ \ \ length\ +=\ dis; length += dis;
}\ \ \ \ \} }
void rightshift(int dis)\ \ \ \ void\ rightshift(int\ dis) void rightshift(int dis)
{\ \ \ \ \{ {
if (dis >= length)\ \ \ \ \ \ \ \ if\ (dis\ >=\ length) if (dis >= length)
{\ \ \ \ \ \ \ \ \{ {
return clear();\ \ \ \ \ \ \ \ \ \ \ \ return\ clear(); return clear();
}\ \ \ \ \ \ \ \ \} }
for (int i = 0; i < length − dis; ++i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ length\ -\ dis;\ ++i) for (int i = 0; i < length − dis; ++i)
{\ \ \ \ \ \ \ \ \{ {
a[i] = a[i + dis];\ \ \ \ \ \ \ \ \ \ \ \ a[i]\ =\ a[i\ +\ dis]; a[i] = a[i + dis];
}\ \ \ \ \ \ \ \ \} }
memset(a + length − dis, 0, sizeof(int) ∗ dis);\ \ \ \ \ \ \ \ memset(a\ +\ length\ -\ dis,\ 0,\ sizeof(int)\ *\ dis); memset(a + length − dis, 0, sizeof(int) ∗ dis);
length = length − dis > 0 ? length − dis : 0;\ \ \ \ \ \ \ \ length\ =\ length\ -\ dis\ >\ 0\ ?\ length\ -\ dis\ :\ 0; length = length − dis > 0 ? length − dis : 0;
}\ \ \ \ \} }
void addone()\ \ \ \ void\ addone() void addone()
{\ \ \ \ \{ {
sig >= 0 ? ++ a[0] : −−a[0];\ \ \ \ \ \ \ \ sig\ >=\ 0\ ?\ ++\ a[0]\ :\ --a[0]; sig >= 0 ? ++ a[0] : −−a[0];
for (int i = 0; i < length; ++i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ length;\ ++i) for (int i = 0; i < length; ++i)
{\ \ \ \ \ \ \ \ \{ {
if (a[i] < 10 && a[i] >= 0)\ \ \ \ \ \ \ \ \ \ \ \ if\ (a[i]\ <\ 10\ \&\&\ a[i]\ >=\ 0) if (a[i] < 10 && a[i] >= 0)
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
break;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ break; break;
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
a[i] >= 10 ? (a[i] −= 10, ++a[i + 1]) : (a[i] += 10, −−a[i + 1]);\ \ \ \ \ \ \ \ \ \ \ \ a[i]\ >=\ 10\ ?\ (a[i]\ -=\ 10,\ ++a[i\ +\ 1])\ :\ (a[i]\ +=\ 10,\ --a[i\ +\ 1]); a[i] >= 10 ? (a[i] −= 10, ++a[i + 1]) : (a[i] += 10, −−a[i + 1]);
}\ \ \ \ \ \ \ \ \} }
if (a[length])\ \ \ \ \ \ \ \ if\ (a[length]) if (a[length])
{\ \ \ \ \ \ \ \ \{ {
++length;\ \ \ \ \ \ \ \ \ \ \ \ ++length; ++length;
}\ \ \ \ \ \ \ \ \} }
if (!a[length − 1])\ \ \ \ \ \ \ \ if\ (!a[length\ -\ 1]) if (!a[length − 1])
{\ \ \ \ \ \ \ \ \{ {
−−length;\ \ \ \ \ \ \ \ \ \ \ \ --length; −−length;
}\ \ \ \ \ \ \ \ \} }
sig = length ? (sig >= 0 ? 1 : −1) : 0;\ \ \ \ \ \ \ \ sig\ =\ length\ ?\ (sig\ >=\ 0\ ?\ 1\ :\ -1)\ :\ 0; sig = length ? (sig >= 0 ? 1 : −1) : 0;
}\ \ \ \ \} }
void minusone()\ \ \ \ void\ minusone() void minusone()
{\ \ \ \ \{ {
sig = −sig;\ \ \ \ \ \ \ \ sig\ =\ -sig; sig = −sig;
addone();\ \ \ \ \ \ \ \ addone(); addone();
sig = −sig;\ \ \ \ \ \ \ \ sig\ =\ -sig; sig = −sig;
}\ \ \ \ \} }
bool absgreaterequal(BigInteger &q)\ \ \ \ bool\ absgreaterequal(BigInteger\ \&q) bool absgreaterequal(BigInteger &q)
{\ \ \ \ \{ {
if (length != q.length)\ \ \ \ \ \ \ \ if\ (length\ !=\ q.length) if (length != q.length)
{\ \ \ \ \ \ \ \ \{ {
return length > q.length;\ \ \ \ \ \ \ \ \ \ \ \ return\ length\ >\ q.length; return length > q.length;
}\ \ \ \ \ \ \ \ \} }
for (int i = length − 1; i >= 0; −− i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ length\ -\ 1;\ i\ >=\ 0;\ --\ i) for (int i = length − 1; i >= 0; −− i)
{\ \ \ \ \ \ \ \ \{ {
if (a[i] > q.a[i])\ \ \ \ \ \ \ \ \ \ \ \ if\ (a[i]\ >\ q.a[i]) if (a[i] > q.a[i])
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
return true;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ true; return true;
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
if (a[i] < q.a[i])\ \ \ \ \ \ \ \ \ \ \ \ if\ (a[i]\ <\ q.a[i]) if (a[i] < q.a[i])
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
return false;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ return\ false; return false;
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
}\ \ \ \ \ \ \ \ \} }
return true;\ \ \ \ \ \ \ \ return\ true; return true;
}\ \ \ \ \} }
void abs()\ \ \ \ void\ abs() void abs()
{\ \ \ \ \{ {
sig = std::abs(sig);\ \ \ \ \ \ \ \ sig\ =\ std::abs(sig); sig = std::abs(sig);
}\ \ \ \ \} }
void neg()\ \ \ \ void\ neg() void neg()
{\ \ \ \ \{ {
sig = −sig;\ \ \ \ \ \ \ \ sig\ =\ -sig; sig = −sig;
}\ \ \ \ \} }
void assign(BigInteger &q)\ \ \ \ void\ assign(BigInteger\ \&q) void assign(BigInteger &q)
{\ \ \ \ \{ {
memset(a, 0, sizeof(int) ∗ length);\ \ \ \ \ \ \ \ memset(a,\ 0,\ sizeof(int)\ *\ length); memset(a, 0, sizeof(int) ∗ length);
memcpy(a, q.a, sizeof(int) ∗ q.length);\ \ \ \ \ \ \ \ memcpy(a,\ q.a,\ sizeof(int)\ *\ q.length); memcpy(a, q.a, sizeof(int) ∗ q.length);
length = q.length;\ \ \ \ \ \ \ \ length\ =\ q.length; length = q.length;
sig = q.sig;\ \ \ \ \ \ \ \ sig\ =\ q.sig; sig = q.sig;
}\ \ \ \ \} }
template <typename T>\ \ \ \ template\ <typename\ T> template <typename T>
void assign(T q)\ \ \ \ void\ assign(T\ q) void assign(T q)
{\ \ \ \ \{ {
memset(a, 0, sizeof(int) ∗ length);\ \ \ \ \ \ \ \ memset(a,\ 0,\ sizeof(int)\ *\ length); memset(a, 0, sizeof(int) ∗ length);
if (!q)\ \ \ \ \ \ \ \ if\ (!q) if (!q)
{\ \ \ \ \ \ \ \ \{ {
return (void)(sig = length = 0);\ \ \ \ \ \ \ \ \ \ \ \ return\ (void)(sig\ =\ length\ =\ 0); return (void)(sig = length = 0);
}\ \ \ \ \ \ \ \ \} }
q < 0 ? sig = −1, q = −q : sig = 1;\ \ \ \ \ \ \ \ q\ <\ 0\ ?\ sig\ =\ -1,\ q\ =\ -q\ :\ sig\ =\ 1; q < 0 ? sig = −1, q = −q : sig = 1;
length = 0;\ \ \ \ \ \ \ \ length\ =\ 0; length = 0;
for (; q; q /= 10)\ \ \ \ \ \ \ \ for\ (;\ q;\ q\ /=\ 10) for (; q; q /= 10)
{\ \ \ \ \ \ \ \ \{ {
a[length++] = q % 10;\ \ \ \ \ \ \ \ \ \ \ \ a[length++]\ =\ q\ \%\ 10; a[length++] = q % 10;
}\ \ \ \ \ \ \ \ \} }
}\ \ \ \ \} }
void add(BigInteger &q)\ \ \ \ void\ add(BigInteger\ \&q) void add(BigInteger &q)
{\ \ \ \ \{ {
static BigInteger aux;\ \ \ \ \ \ \ \ static\ BigInteger\ aux; static BigInteger aux;
if (!q.sig)\ \ \ \ \ \ \ \ if\ (!q.sig) if (!q.sig)
{\ \ \ \ \ \ \ \ \{ {
return ;\ \ \ \ \ \ \ \ \ \ \ \ return\ ; return ;
}\ \ \ \ \ \ \ \ \} }
if (!sig)\ \ \ \ \ \ \ \ if\ (!sig) if (!sig)
{\ \ \ \ \ \ \ \ \{ {
assign(q);\ \ \ \ \ \ \ \ \ \ \ \ assign(q); assign(q);
return ;\ \ \ \ \ \ \ \ \ \ \ \ return\ ; return ;
}\ \ \ \ \ \ \ \ \} }
if (sig == q.sig)\ \ \ \ \ \ \ \ if\ (sig\ ==\ q.sig) if (sig == q.sig)
{\ \ \ \ \ \ \ \ \{ {
addminus(a, q.a, length, q.length, 1);\ \ \ \ \ \ \ \ \ \ \ \ addminus(a,\ q.a,\ length,\ q.length,\ 1); addminus(a, q.a, length, q.length, 1);
return ;\ \ \ \ \ \ \ \ \ \ \ \ return\ ; return ;
}\ \ \ \ \ \ \ \ \} }
if (absgreaterequal(q))\ \ \ \ \ \ \ \ if\ (absgreaterequal(q)) if (absgreaterequal(q))
{\ \ \ \ \ \ \ \ \{ {
addminus(a, q.a, length, q.length, −1);\ \ \ \ \ \ \ \ \ \ \ \ addminus(a,\ q.a,\ length,\ q.length,\ -1); addminus(a, q.a, length, q.length, −1);
sig = length ? sig : 0;\ \ \ \ \ \ \ \ \ \ \ \ sig\ =\ length\ ?\ sig\ :\ 0; sig = length ? sig : 0;
return ;\ \ \ \ \ \ \ \ \ \ \ \ return\ ; return ;
}\ \ \ \ \ \ \ \ \} }
aux.assign(q);\ \ \ \ \ \ \ \ aux.assign(q); aux.assign(q);
addminus(q.a, a, q.length, length, −1);\ \ \ \ \ \ \ \ addminus(q.a,\ a,\ q.length,\ length,\ -1); addminus(q.a, a, q.length, length, −1);
assign(q);\ \ \ \ \ \ \ \ assign(q); assign(q);
q.assign(aux);\ \ \ \ \ \ \ \ q.assign(aux); q.assign(aux);
}\ \ \ \ \} }
void minus(BigInteger &q)\ \ \ \ void\ minus(BigInteger\ \&q) void minus(BigInteger &q)
{\ \ \ \ \{ {
q.neg();\ \ \ \ \ \ \ \ q.neg(); q.neg();
add(q);\ \ \ \ \ \ \ \ add(q); add(q);
q.neg();\ \ \ \ \ \ \ \ q.neg(); q.neg();
}\ \ \ \ \} }
void NTT(int ∗a, int length, int type)\ \ \ \ void\ NTT(int\ *a,\ int\ length,\ int\ type) void NTT(int ∗a, int length, int type)
{\ \ \ \ \{ {
int len = −1;\ \ \ \ \ \ \ \ int\ len\ =\ -1; int len = −1;
for (int x = length; x; ++len, x >>= 1) ;\ \ \ \ \ \ \ \ for\ (int\ x\ =\ length;\ x;\ ++len,\ x\ >>=\ 1)\ ; for (int x = length; x; ++len, x >>= 1) ;
for (int i = 1, j = 0; i < length − 1; ++i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ 1,\ j\ =\ 0;\ i\ <\ length\ -\ 1;\ ++i) for (int i = 1, j = 0; i < length − 1; ++i)
{\ \ \ \ \ \ \ \ \{ {
for (int s = length; j ∧= s >>= 1, j & s; ) ;\ \ \ \ \ \ \ \ \ \ \ \ for\ (int\ s\ =\ length;\ j\ \wedge =\ s\ >>=\ 1,\ ~j\ \&\ s;\ )\ ; for (int s = length; j ∧= s >>= 1, j & s; ) ;
if (i < j)\ \ \ \ \ \ \ \ \ \ \ \ if\ (i\ <\ j) if (i < j)
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
std::swap(a[i], a[j]);\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ std::swap(a[i],\ a[j]); std::swap(a[i], a[j]);
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
}\ \ \ \ \ \ \ \ \} }
for (int i = 1; i <= len; ++ i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ 1;\ i\ <=\ len;\ ++\ i) for (int i = 1; i <= len; ++ i)
{\ \ \ \ \ \ \ \ \{ {
int unit = powermod(type == 1 ? root : invroot, (MOD − 1) >> i, MOD), szk = 1 << (i − 1);\ \ \ \ \ \ \ \ \ \ \ \ int\ unit\ =\ powermod(type\ ==\ 1\ ?\ root\ :\ invroot,\ (MOD\ -\ 1)\ >>\ i,\ MOD),\ szk\ =\ 1\ <<\ (i\ -\ 1); int unit = powermod(type == 1 ? root : invroot, (MOD − 1) >> i, MOD), szk = 1 << (i − 1);
for (int j = 0; j < length; j += 1 << i)\ \ \ \ \ \ \ \ \ \ \ \ for\ (int\ j\ =\ 0;\ j\ <\ length;\ j\ +=\ 1\ <<\ i) for (int j = 0; j < length; j += 1 << i)
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
for (int k = j, w = 1; k < j + szk; ++k)\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ for\ (int\ k\ =\ j,\ w\ =\ 1;\ k\ <\ j\ +\ szk;\ ++k) for (int k = j, w = 1; k < j + szk; ++k)
{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \{ {
int s = a[k], t = 1ll ∗ w ∗ a[k + szk] % MOD;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ int\ s\ =\ a[k],\ t\ =\ 1ll\ *\ w\ *\ a[k\ +\ szk]\ \%\ MOD; int s = a[k], t = 1ll ∗ w ∗ a[k + szk] % MOD;
a[k] = s + t >= MOD ? s + t − MOD : s + t;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ a[k]\ =\ s\ +\ t\ >=\ MOD\ ?\ s\ +\ t\ -\ MOD\ :\ s\ +\ t; a[k] = s + t >= MOD ? s + t − MOD : s + t;
a[k + szk] = s − t < 0 ? s − t + MOD : s − t;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ a[k\ +\ szk]\ =\ s\ -\ t\ <\ 0\ ?\ s\ -\ t\ +\ MOD\ :\ s\ -\ t; a[k + szk] = s − t < 0 ? s − t + MOD : s − t;
w = 1ll ∗ w ∗ unit % MOD;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ w\ =\ 1ll\ *\ w\ *\ unit\ \%\ MOD; w = 1ll ∗ w ∗ unit % MOD;
}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \} }
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
}\ \ \ \ \ \ \ \ \} }
if (type == 1)\ \ \ \ \ \ \ \ if\ (type\ ==\ 1) if (type == 1)
{\ \ \ \ \ \ \ \ \{ {
return ;\ \ \ \ \ \ \ \ \ \ \ \ return\ ; return ;
}\ \ \ \ \ \ \ \ \} }
int inv = powermod(length, MOD − 2, MOD);\ \ \ \ \ \ \ \ int\ inv\ =\ powermod(length,\ MOD\ -\ 2,\ MOD); int inv = powermod(length, MOD − 2, MOD);
for (int i = 0; i < length; ++ i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ length;\ ++\ i) for (int i = 0; i < length; ++ i)
{\ \ \ \ \ \ \ \ \{ {
a[i] = 1ll ∗ a[i] ∗ inv % MOD;\ \ \ \ \ \ \ \ \ \ \ \ a[i]\ =\ 1ll\ *\ a[i]\ *\ inv\ \%\ MOD; a[i] = 1ll ∗ a[i] ∗ inv % MOD;
}\ \ \ \ \ \ \ \ \} }
}\ \ \ \ \} }
void mult(BigInteger &q)\ \ \ \ void\ mult(BigInteger\ \&q) void mult(BigInteger &q)
{\ \ \ \ \{ {
static int aux[1 << MAXN];\ \ \ \ \ \ \ \ static\ int\ aux[1\ <<\ MAXN]; static int aux[1 << MAXN];
if (!sig ∣∣ !q.sig)\ \ \ \ \ \ \ \ if\ (!sig\ ||\ !q.sig) if (!sig ∣∣ !q.sig)
{\ \ \ \ \ \ \ \ \{ {
return clear();\ \ \ \ \ \ \ \ \ \ \ \ return\ clear(); return clear();
}\ \ \ \ \ \ \ \ \} }
int n = length + q.length;\ \ \ \ \ \ \ \ int\ n\ =\ length\ +\ q.length; int n = length + q.length;
int lengthans = 1;\ \ \ \ \ \ \ \ int\ lengthans\ =\ 1; int lengthans = 1;
for (; lengthans < n; lengthans <<= 1) ;\ \ \ \ \ \ \ \ for\ (;\ lengthans\ <\ n;\ lengthans\ <<=\ 1)\ ; for (; lengthans < n; lengthans <<= 1) ;
memcpy(aux, q.a, sizeof(int) ∗ lengthans);\ \ \ \ \ \ \ \ memcpy(aux,\ q.a,\ sizeof(int)\ *\ lengthans); memcpy(aux, q.a, sizeof(int) ∗ lengthans);
NTT(a, lengthans, 1);\ \ \ \ \ \ \ \ NTT(a,\ lengthans,\ 1); NTT(a, lengthans, 1);
NTT(aux, lengthans, 1);\ \ \ \ \ \ \ \ NTT(aux,\ lengthans,\ 1); NTT(aux, lengthans, 1);
for (int i = 0; i < lengthans; i++)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ lengthans;\ i++) for (int i = 0; i < lengthans; i++)
{\ \ \ \ \ \ \ \ \{ {
a[i] = 1ll ∗ a[i] ∗ aux[i] % MOD;\ \ \ \ \ \ \ \ \ \ \ \ a[i]\ =\ 1ll\ *\ a[i]\ *\ aux[i]\ \%\ MOD; a[i] = 1ll ∗ a[i] ∗ aux[i] % MOD;
}\ \ \ \ \ \ \ \ \} }
NTT(a, lengthans, −1);\ \ \ \ \ \ \ \ NTT(a,\ lengthans,\ -1); NTT(a, lengthans, −1);
for (int i = 0; i < n − 1; i++)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ n\ -\ 1;\ i++) for (int i = 0; i < n − 1; i++)
{\ \ \ \ \ \ \ \ \{ {
a[i + 1] += a[i] / 10;\ \ \ \ \ \ \ \ \ \ \ \ a[i\ +\ 1]\ +=\ a[i]\ /\ 10; a[i + 1] += a[i] / 10;
a[i] %= 10;\ \ \ \ \ \ \ \ \ \ \ \ a[i]\ \%=\ 10; a[i] %= 10;
}\ \ \ \ \ \ \ \ \} }
length = n;\ \ \ \ \ \ \ \ length\ =\ n; length = n;
for (; length && !a[length − 1]; −−length) ;\ \ \ \ \ \ \ \ for\ (;\ length\ \&\&\ !a[length\ -\ 1];\ --length)\ ; for (; length && !a[length − 1]; −−length) ;
sig ∗= q.sig;\ \ \ \ \ \ \ \ sig\ *=\ q.sig; sig ∗= q.sig;
}\ \ \ \ \} }
void mult(int q)\ \ \ \ void\ mult(int\ q) void mult(int q)
{\ \ \ \ \{ {
if (!q ∣∣ !sig)\ \ \ \ \ \ \ \ if\ (!q\ ||\ !sig) if (!q ∣∣ !sig)
{\ \ \ \ \ \ \ \ \{ {
return clear();\ \ \ \ \ \ \ \ \ \ \ \ return\ clear(); return clear();
}\ \ \ \ \ \ \ \ \} }
ll x = std::abs(q), remain = 0;\ \ \ \ \ \ \ \ ll\ x\ =\ std::abs(q),\ remain\ =\ 0; ll x = std::abs(q), remain = 0;
for (int i = 0; i < length; ++i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ 0;\ i\ <\ length;\ ++i) for (int i = 0; i < length; ++i)
{\ \ \ \ \ \ \ \ \{ {
remain += a[i] ∗ x;\ \ \ \ \ \ \ \ \ \ \ \ remain\ +=\ a[i]\ *\ x; remain += a[i] ∗ x;
a[i] = remain % 10;\ \ \ \ \ \ \ \ \ \ \ \ a[i]\ =\ remain\ \%\ 10; a[i] = remain % 10;
remain /= 10;\ \ \ \ \ \ \ \ \ \ \ \ remain\ /=\ 10; remain /= 10;
}\ \ \ \ \ \ \ \ \} }
a[length] = (int)remain;\ \ \ \ \ \ \ \ a[length]\ =\ (int)remain; a[length] = (int)remain;
for (; a[length]; ++length)\ \ \ \ \ \ \ \ for\ (;\ a[length];\ ++length) for (; a[length]; ++length)
{\ \ \ \ \ \ \ \ \{ {
a[length + 1] = a[length] / 10;\ \ \ \ \ \ \ \ \ \ \ \ a[length\ +\ 1]\ =\ a[length]\ /\ 10; a[length + 1] = a[length] / 10;
a[length] %= 10;\ \ \ \ \ \ \ \ \ \ \ \ a[length]\ \%=\ 10; a[length] %= 10;
}\ \ \ \ \ \ \ \ \} }
for (; length && !a[length − 1]; −−length) ;\ \ \ \ \ \ \ \ for\ (;\ length\ \&\&\ !a[length\ -\ 1];\ --length)\ ; for (; length && !a[length − 1]; −−length) ;
sig ∗= q < 0 ? −1 : 1;\ \ \ \ \ \ \ \ sig\ *=\ q\ <\ 0\ ?\ -1\ :\ 1; sig ∗= q < 0 ? −1 : 1;
}\ \ \ \ \} }
void power(int exp)\ \ \ \ void\ power(int\ exp) void power(int exp)
{\ \ \ \ \{ {
static BigInteger aux;\ \ \ \ \ \ \ \ static\ BigInteger\ aux; static BigInteger aux;
if (!sig)\ \ \ \ \ \ \ \ if\ (!sig) if (!sig)
{\ \ \ \ \ \ \ \ \{ {
return ;\ \ \ \ \ \ \ \ \ \ \ \ return\ ; return ;
}\ \ \ \ \ \ \ \ \} }
aux.assign<int> (1);\ \ \ \ \ \ \ \ aux.assign<int>\ (1); aux.assign<int> (1);
for (; exp; exp >>= 1)\ \ \ \ \ \ \ \ for\ (;\ exp;\ exp\ >>=\ 1) for (; exp; exp >>= 1)
{\ \ \ \ \ \ \ \ \{ {
if (exp & 1)\ \ \ \ \ \ \ \ \ \ \ \ if\ (exp\ \&\ 1) if (exp & 1)
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
aux.mult(∗this);\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ aux.mult(*this); aux.mult(∗this);
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
aux.mult(aux);\ \ \ \ \ \ \ \ \ \ \ \ aux.mult(aux); aux.mult(aux);
}\ \ \ \ \ \ \ \ \} }
assign(aux);\ \ \ \ \ \ \ \ assign(aux); assign(aux);
}\ \ \ \ \} }
void divide(BigInteger &q)\ \ \ \ void\ divide(BigInteger\ \&q) void divide(BigInteger &q)
{\ \ \ \ \{ {
static BigInteger aux, aux1;\ \ \ \ \ \ \ \ static\ BigInteger\ aux,\ aux1; static BigInteger aux, aux1;
if (!sig ∣∣ !q.sig)\ \ \ \ \ \ \ \ if\ (!sig\ ||\ !q.sig) if (!sig ∣∣ !q.sig)
{\ \ \ \ \ \ \ \ \{ {
return ;\ \ \ \ \ \ \ \ \ \ \ \ return\ ; return ;
}\ \ \ \ \ \ \ \ \} }
if (length < q.length)\ \ \ \ \ \ \ \ if\ (length\ <\ q.length) if (length < q.length)
{\ \ \ \ \ \ \ \ \{ {
return clear();\ \ \ \ \ \ \ \ \ \ \ \ return\ clear(); return clear();
}\ \ \ \ \ \ \ \ \} }
bool neg1 = sig == 1, neg2 = q.sig == 1;\ \ \ \ \ \ \ \ bool\ neg1\ =\ sig\ ==\ 1,\ neg2\ =\ q.sig\ ==\ 1; bool neg1 = sig == 1, neg2 = q.sig == 1;
abs(), q.abs();\ \ \ \ \ \ \ \ abs(),\ q.abs(); abs(), q.abs();
int num = 0;\ \ \ \ \ \ \ \ int\ num\ =\ 0; int num = 0;
for (int i = q.length − 1; i >= q.length − 3; −−i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ q.length\ -\ 1;\ i\ >=\ q.length\ -\ 3;\ --i) for (int i = q.length − 1; i >= q.length − 3; −−i)
{\ \ \ \ \ \ \ \ \{ {
(num ∗= 10) += i >= 0 ? q.a[i] : 0;\ \ \ \ \ \ \ \ \ \ \ \ (num\ *=\ 10)\ +=\ i\ >=\ 0\ ?\ q.a[i]\ :\ 0; (num ∗= 10) += i >= 0 ? q.a[i] : 0;
}\ \ \ \ \ \ \ \ \} }
num = 100000 / num;\ \ \ \ \ \ \ \ num\ =\ 100000\ /\ num; num = 100000 / num;
int nowprecision = 1;\ \ \ \ \ \ \ \ int\ nowprecision\ =\ 1; int nowprecision = 1;
aux.assign<int> (num);\ \ \ \ \ \ \ \ aux.assign<int>\ (num); aux.assign<int> (num);
for (; nowprecision <= length − q.length; nowprecision <<= 1)\ \ \ \ \ \ \ \ for\ (;\ nowprecision\ <=\ length\ -\ q.length;\ nowprecision\ <<=\ 1) for (; nowprecision <= length − q.length; nowprecision <<= 1)
{\ \ \ \ \ \ \ \ \{ {
aux1.clear();\ \ \ \ \ \ \ \ \ \ \ \ aux1.clear(); aux1.clear();
aux1.length = (nowprecision << 1) + 3, aux1.sig = 1;\ \ \ \ \ \ \ \ \ \ \ \ aux1.length\ =\ (nowprecision\ <<\ 1)\ +\ 3,\ aux1.sig\ =\ 1; aux1.length = (nowprecision << 1) + 3, aux1.sig = 1;
for (int i = q.length − aux1.length; i < q.length; ++i)\ \ \ \ \ \ \ \ \ \ \ \ for\ (int\ i\ =\ q.length\ -\ aux1.length;\ i\ <\ q.length;\ ++i) for (int i = q.length − aux1.length; i < q.length; ++i)
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
aux1.a[i − q.length + aux1.length] = i >= 0 ? q.a[i] : 0;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ aux1.a[i\ -\ q.length\ +\ aux1.length]\ =\ i\ >=\ 0\ ?\ q.a[i]\ :\ 0; aux1.a[i − q.length + aux1.length] = i >= 0 ? q.a[i] : 0;
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
aux1.mult(aux), aux1.rightshift(nowprecision + 2);\ \ \ \ \ \ \ \ \ \ \ \ aux1.mult(aux),\ aux1.rightshift(nowprecision\ +\ 2); aux1.mult(aux), aux1.rightshift(nowprecision + 2);
aux1.mult(aux), aux1.rightshift(nowprecision + 2);\ \ \ \ \ \ \ \ \ \ \ \ aux1.mult(aux),\ aux1.rightshift(nowprecision\ +\ 2); aux1.mult(aux), aux1.rightshift(nowprecision + 2);
aux.mult(2);\ \ \ \ \ \ \ \ \ \ \ \ aux.mult(2); aux.mult(2);
aux.leftshift(nowprecision);\ \ \ \ \ \ \ \ \ \ \ \ aux.leftshift(nowprecision); aux.leftshift(nowprecision);
aux.minus(aux1);\ \ \ \ \ \ \ \ \ \ \ \ aux.minus(aux1); aux.minus(aux1);
}\ \ \ \ \ \ \ \ \} }
aux.mult(∗this);\ \ \ \ \ \ \ \ aux.mult(*this); aux.mult(∗this);
aux.rightshift(q.length + nowprecision + 1);\ \ \ \ \ \ \ \ aux.rightshift(q.length\ +\ nowprecision\ +\ 1); aux.rightshift(q.length + nowprecision + 1);
aux1.assign(aux);\ \ \ \ \ \ \ \ aux1.assign(aux); aux1.assign(aux);
aux1.mult(q);\ \ \ \ \ \ \ \ aux1.mult(q); aux1.mult(q);
minus(aux1);\ \ \ \ \ \ \ \ minus(aux1); minus(aux1);
int flag = absgreaterequal(q) ? 2 : sig < 0 ? 1 : 0;\ \ \ \ \ \ \ \ int\ flag\ =\ absgreaterequal(q)\ ?\ 2\ :\ sig\ <\ 0\ ?\ 1\ :\ 0; int flag = absgreaterequal(q) ? 2 : sig < 0 ? 1 : 0;
assign(aux);\ \ \ \ \ \ \ \ assign(aux); assign(aux);
if (flag)\ \ \ \ \ \ \ \ if\ (flag) if (flag)
{\ \ \ \ \ \ \ \ \{ {
flag == 1 ? minusone() : addone();\ \ \ \ \ \ \ \ \ \ \ \ flag\ ==\ 1\ ?\ minusone()\ :\ addone(); flag == 1 ? minusone() : addone();
}\ \ \ \ \ \ \ \ \} }
if (!neg2)\ \ \ \ \ \ \ \ if\ (!neg2) if (!neg2)
{\ \ \ \ \ \ \ \ \{ {
q.neg();\ \ \ \ \ \ \ \ \ \ \ \ q.neg(); q.neg();
}\ \ \ \ \ \ \ \ \} }
sig ∗= neg1 ∧ neg2 ? −1 : 1;\ \ \ \ \ \ \ \ sig\ *=\ neg1\ \wedge \ neg2\ ?\ -1\ :\ 1; sig ∗= neg1 ∧ neg2 ? −1 : 1;
}\ \ \ \ \} }
int divide(int q)\ \ \ \ int\ divide(int\ q) int divide(int q)
{\ \ \ \ \{ {
if (!sig ∣∣ !q)\ \ \ \ \ \ \ \ if\ (!sig\ ||\ !q) if (!sig ∣∣ !q)
{\ \ \ \ \ \ \ \ \{ {
return 0;\ \ \ \ \ \ \ \ \ \ \ \ return\ 0; return 0;
}\ \ \ \ \ \ \ \ \} }
ll remain = 0, x = std::abs(q);\ \ \ \ \ \ \ \ ll\ remain\ =\ 0,\ x\ =\ std::abs(q); ll remain = 0, x = std::abs(q);
for (int i = length − 1; i >= 0; −−i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ length\ -\ 1;\ i\ >=\ 0;\ --i) for (int i = length − 1; i >= 0; −−i)
{\ \ \ \ \ \ \ \ \{ {
remain = remain ∗ 10 + a[i];\ \ \ \ \ \ \ \ \ \ \ \ remain\ =\ remain\ *\ 10\ +\ a[i]; remain = remain ∗ 10 + a[i];
a[i] = (int)(remain / x);\ \ \ \ \ \ \ \ \ \ \ \ a[i]\ =\ (int)(remain\ /\ x); a[i] = (int)(remain / x);
remain %= x;\ \ \ \ \ \ \ \ \ \ \ \ remain\ \%=\ x; remain %= x;
}\ \ \ \ \ \ \ \ \} }
for (; length && !a[length − 1]; −−length) ;\ \ \ \ \ \ \ \ for\ (;\ length\ \&\&\ !a[length\ -\ 1];\ --length)\ ; for (; length && !a[length − 1]; −−length) ;
remain ∗= sig;\ \ \ \ \ \ \ \ remain\ *=\ sig; remain ∗= sig;
sig ∗= q < 0 ? −1 : 1;\ \ \ \ \ \ \ \ sig\ *=\ q\ <\ 0\ ?\ -1\ :\ 1; sig ∗= q < 0 ? −1 : 1;
if (!length)\ \ \ \ \ \ \ \ if\ (!length) if (!length)
{\ \ \ \ \ \ \ \ \{ {
sig = 0;\ \ \ \ \ \ \ \ \ \ \ \ sig\ =\ 0; sig = 0;
}\ \ \ \ \ \ \ \ \} }
return (int)remain;\ \ \ \ \ \ \ \ return\ (int)remain; return (int)remain;
}\ \ \ \ \} }
void sqrt()\ \ \ \ void\ sqrt() void sqrt()
{\ \ \ \ \{ {
static BigInteger aux, aux1, aux2;\ \ \ \ \ \ \ \ static\ BigInteger\ aux,\ aux1,\ aux2; static BigInteger aux, aux1, aux2;
if (sig <= 0)\ \ \ \ \ \ \ \ if\ (sig\ <=\ 0) if (sig <= 0)
{\ \ \ \ \ \ \ \ \{ {
return ;\ \ \ \ \ \ \ \ \ \ \ \ return\ ; return ;
}\ \ \ \ \ \ \ \ \} }
int num = 0;\ \ \ \ \ \ \ \ int\ num\ =\ 0; int num = 0;
for (int i = length − 1; i >= length − 8; −−i)\ \ \ \ \ \ \ \ for\ (int\ i\ =\ length\ -\ 1;\ i\ >=\ length\ -\ 8;\ --i) for (int i = length − 1; i >= length − 8; −−i)
{\ \ \ \ \ \ \ \ \{ {
(num ∗= 10) += i >= 0 ? a[i] : 0;\ \ \ \ \ \ \ \ \ \ \ \ (num\ *=\ 10)\ +=\ i\ >=\ 0\ ?\ a[i]\ :\ 0; (num ∗= 10) += i >= 0 ? a[i] : 0;
}\ \ \ \ \ \ \ \ \} }
ll x = length & 1 ? 10000000000000ll : 100000000000000ll;\ \ \ \ \ \ \ \ ll\ x\ =\ length\ \&\ 1\ ?\ 10000000000000ll\ :\ 100000000000000ll; ll x = length & 1 ? 10000000000000ll : 100000000000000ll;
num = std::sqrt(1.0 ∗ x / num);\ \ \ \ \ \ \ \ num\ =\ std::sqrt(1.0\ *\ x\ /\ num); num = std::sqrt(1.0 ∗ x / num);
int nowprecision = 2;\ \ \ \ \ \ \ \ int\ nowprecision\ =\ 2; int nowprecision = 2;
aux.assign<int> (num);\ \ \ \ \ \ \ \ aux.assign<int>\ (num); aux.assign<int> (num);
for (; nowprecision <= (length >> 1) + 1; nowprecision = (nowprecision << 1) − 1)\ \ \ \ \ \ \ \ for\ (;\ nowprecision\ <=\ (length\ >>\ 1)\ +\ 1;\ nowprecision\ =\ (nowprecision\ <<\ 1)\ -\ 1) for (; nowprecision <= (length >> 1) + 1; nowprecision = (nowprecision << 1) − 1)
{\ \ \ \ \ \ \ \ \{ {
aux1.clear(), aux2.clear();\ \ \ \ \ \ \ \ \ \ \ \ aux1.clear(),\ aux2.clear(); aux1.clear(), aux2.clear();
aux1.length = (nowprecision << 1) + 1 + (length & 1), aux1.sig = 1;\ \ \ \ \ \ \ \ \ \ \ \ aux1.length\ =\ (nowprecision\ <<\ 1)\ +\ 1\ +\ (length\ \&\ 1),\ aux1.sig\ =\ 1; aux1.length = (nowprecision << 1) + 1 + (length & 1), aux1.sig = 1;
for (int i = length − aux1.length; i < length; ++i)\ \ \ \ \ \ \ \ \ \ \ \ for\ (int\ i\ =\ length\ -\ aux1.length;\ i\ <\ length;\ ++i) for (int i = length − aux1.length; i < length; ++i)
{\ \ \ \ \ \ \ \ \ \ \ \ \{ {
aux1.a[i − length + aux1.length] = i >= 0 ? a[i] : 0;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ aux1.a[i\ -\ length\ +\ aux1.length]\ =\ i\ >=\ 0\ ?\ a[i]\ :\ 0; aux1.a[i − length + aux1.length] = i >= 0 ? a[i] : 0;
}\ \ \ \ \ \ \ \ \ \ \ \ \} }
aux1.mult(aux), aux1.rightshift(nowprecision + 1);\ \ \ \ \ \ \ \ \ \ \ \ aux1.mult(aux),\ aux1.rightshift(nowprecision\ +\ 1); aux1.mult(aux), aux1.rightshift(nowprecision + 1);
aux1.mult(aux), aux1.rightshift(nowprecision + 1);\ \ \ \ \ \ \ \ \ \ \ \ aux1.mult(aux),\ aux1.rightshift(nowprecision\ +\ 1); aux1.mult(aux), aux1.rightshift(nowprecision + 1);
aux1.divide(2);\ \ \ \ \ \ \ \ \ \ \ \ aux1.divide(2); aux1.divide(2);
aux2.length = (nowprecision + 1) << 1, aux2.sig = 1;\ \ \ \ \ \ \ \ \ \ \ \ aux2.length\ =\ (nowprecision\ +\ 1)\ <<\ 1,\ aux2.sig\ =\ 1; aux2.length = (nowprecision + 1) << 1, aux2.sig = 1;
aux2.a[aux2.length − 1] = 1, aux2.a[aux2.length − 2] = 5;\ \ \ \ \ \ \ \ \ \ \ \ aux2.a[aux2.length\ -\ 1]\ =\ 1,\ aux2.a[aux2.length\ -\ 2]\ =\ 5; aux2.a[aux2.length − 1] = 1, aux2.a[aux2.length − 2] = 5;
aux2.minus(aux1);\ \ \ \ \ \ \ \ \ \ \ \ aux2.minus(aux1); aux2.minus(aux1);
aux.mult(aux2);\ \ \ \ \ \ \ \ \ \ \ \ aux.mult(aux2); aux.mult(aux2);
aux.rightshift(nowprecision + 2);\ \ \ \ \ \ \ \ \ \ \ \ aux.rightshift(nowprecision\ +\ 2); aux.rightshift(nowprecision + 2);
}\ \ \ \ \ \ \ \ \} }
aux.mult(∗this);\ \ \ \ \ \ \ \ aux.mult(*this); aux.mult(∗this);
aux.rightshift((length >> 1) + nowprecision + 1);\ \ \ \ \ \ \ \ aux.rightshift((length\ >>\ 1)\ +\ nowprecision\ +\ 1); aux.rightshift((length >> 1) + nowprecision + 1);
aux1.assign(aux);\ \ \ \ \ \ \ \ aux1.assign(aux); aux1.assign(aux);
aux1.mult(aux1);\ \ \ \ \ \ \ \ aux1.mult(aux1); aux1.mult(aux1);
aux2.assign(∗this);\ \ \ \ \ \ \ \ aux2.assign(*this); aux2.assign(∗this);
aux2.mult(2);\ \ \ \ \ \ \ \ aux2.mult(2); aux2.mult(2);
minus(aux1);\ \ \ \ \ \ \ \ minus(aux1); minus(aux1);
int flag = greater(aux2) ? 2 : sig < 0 ? 1 : 0;\ \ \ \ \ \ \ \ int\ flag\ =\ greater(aux2)\ ?\ 2\ :\ sig\ <\ 0\ ?\ 1\ :\ 0; int flag = greater(aux2) ? 2 : sig < 0 ? 1 : 0;
assign(aux);\ \ \ \ \ \ \ \ assign(aux); assign(aux);
if (flag)\ \ \ \ \ \ \ \ if\ (flag) if (flag)
{\ \ \ \ \ \ \ \ \{ {
flag == 1 ? minusone() : addone();\ \ \ \ \ \ \ \ \ \ \ \ flag\ ==\ 1\ ?\ minusone()\ :\ addone(); flag == 1 ? minusone() : addone();
}\ \ \ \ \ \ \ \ \} }
}\ \ \ \ \} }
};\};};
BigInteger a, b, c;BigInteger\ a,\ b,\ c;BigInteger a, b, c;
int main()int\ main()int main()
{\{{
a.read();\ \ \ \ a.read(); a.read();
b.read();\ \ \ \ b.read(); b.read();
c.assign(a);\ \ \ \ c.assign(a); c.assign(a);
a.divide(b);\ \ \ \ a.divide(b); a.divide(b);
a.write();\ \ \ \ a.write(); a.write();
putchar(′\n′);\ \ \ \ putchar('\backslash n'); putchar(′\n′);
a.mult(b);\ \ \ \ a.mult(b); a.mult(b);
c.minus(a);\ \ \ \ c.minus(a); c.minus(a);
c.write();\ \ \ \ c.write(); c.write();
putchar(′\n′);\ \ \ \ putchar('\backslash n'); putchar(′\n′);
return 0;\ \ \ \ return\ 0; return 0;
}\}}
$
这篇博客主要介绍了如何使用LaTeX进行字符串匹配算法的实现,包括SAM、AAM和BAM算法,并展示了大整数的加减乘除运算。通过代码示例,阐述了字符串匹配的原理以及大整数运算的处理方法,适合对算法和数学计算感兴趣的读者阅读。
4742

被折叠的 条评论
为什么被折叠?



