PS:以后把模板就放这里了~qwq
常用定义
#define M(a,b) memset(a,(b),sizof(a))
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define R(i,a,b) for(register int i=(b);i>=(a);i--)
#define E(i,u) for(register int i=head[u];i;i=nxt[i])
typedef long long LL;
数学
筛法
线性筛质数
void getpri() {
int tot=0;
for(int i=2;i<=n;i++) {
if(!vis[i]) pri[++tot]=i;
for(int j=1;i*j<=n&&j<=cnt;j++) {
vis[i*pri[j]]=1;
if(i%pri[j]==0) break;
}
}
}
欧拉函数
void getphi() {
int tot=0;
for(int i=2;i<=n;i++) {
if(!vis[i]) pri[i]=i,phi[i]=i-1;
for(int j=1;j<=tot&&i*j<=n;j++) {
vis[i*pri[j]]=1;
if(i%pri[j]==0) {
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
}
}
莫比乌斯函数
void getmu() {
int tot=0;
for(int i=1;i<=n;i++) {
if(!vis[i]) pri[++tot]=i,mu[i]=-1;
for(int j=1;j<=tot&&i*j<=n;j++) {
vis[i*pri[j]]=1;
if(i%pri[j]==0) break;//mu[i*pri[j]]=0;
mu[i*pri[j]]=-mu[i];
}
}
}
快速幂
typedef long long LL;
LL qpow(LL a,LL b) {//无模数
LL t=1;
while(b) {
if(b&1) t*=a;
a*=a; b>>=1;
}
return t;
}
LL qpow(LL a,LL b,LL q) {//有模数
LL t=1;
while(b) {
if(b&1) t=t*a%p;
a=a*a%p; b>>=1;
}
return t;
}
矩阵乘法&快速幂
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define M(a,b) memset(a,(b),sizof(a))
const int N=510;
int n;
struct Matrix{
int da[N][N];
void clear() {M(da,0);}
Matrix operator * (const Matrix oth) {
Matrix t;
F(i,1,n) F(j,1,n) F(k,1,n)
t.da[i][j]=da[i][k]*oth.da[k][j];
return t;
}
}
Matrix Qpow(Matrix a,int b) {//快速幂
Matrix t;
F(i,1,n) t.da[i][i]=1;
while(b) {
if(b&1) t=t*a;
a=a*a; b>>=1;
}
return t;
}
字符串
AC自动机
queue <int> Q;
struct Aho_Corasick_Automation{
int nd[N][26],val[N],fail[N],cnt;
void ins(char *s) {
int len=strlen(s),now=0;
F(i,0,len-1) {
int v=s[i]-'a';
if(!nd[now][v]) nd[now][v]=++cnt;
now=nd[now][v];
}
val[now]++;
}
void build() {
F(i,0,26-1) if(nd[0][i]) fail[nd[0][i]]=0,Q.push(nd[0][i]);
while(!Q.empty()) {
int u=Q.front(); Q.pop();
F(i,0,26-1)
if(nd[u][i]) fail[nd[u][i]]=nd[fail[u]][i],Q.push(nd[u][i]);
else nd[u][i]=nd[fail[u]][i];
}
}
int query(char *s) {
int len=strlen(s),now=0,ans=0;
F(i,0,len-1) {
now=nd[now][s[i]-'a'];
for(int t=now;t&&~val[t];t=fail[t]) ans+=val[t],val[t]=-1;
}
return ans;
}
}AC;
数据结构
左偏树
int nd[N][2],dis[N],val[N],fa[N];
#define ls nd[x][0]
#define rs nd[x][1]
int merge(int x,int y) {
if(!x||!y) return x+y;
if(val[x]>val[y]||(val[x]==val[y]&&x>y)) swap(x,y);
fa[rs=merge(rs,y)]=x;
if(dis[ls]<dis[rs]) swap(ls,rs);
dis[x]=dis[rs]+1;
return x;
}
void pop(int x) {
val[x]=-1; fa[ls]=fa[rs]=0;
merge(ls,rs);
}
int getf(int x) {
while(fa[x]) x=fa[x]; return x;
}
其他
高精度
(希望没错qwq)
PS:建议复制下来查看~
struct bign{
int len,s[MAXL]; bool sign;
bign() {M(s,0);len=sign=1;}
bign(const char *num) {*this=num;}
bign(int num) {*this=num;};
string tostr() const {
string res="";
F(i,0,len-1) res=(char)(s[i]+'0')+res;
if(res=="") res="0";
if(!sign&&res!="0") res="-"+res;
return res;
}
friend istream &operator>>(istream &in,bign &num) {string str;in>>str;num=str;return in;}
friend ostream &operator<<(ostream &out,bign &num) {out<<num.tostr();return out;}
bign operator=(const char *num) {
M(s,0);
char a[MAXL]="";
if(num[0]!='-') strcpy(a,num);
else { int Len=strlen(num);
F(i,1,Len-1) a[i-1]=num[i];
}
sign=!(num[0]=='-');
len=strlen(a);
F(i,0,len-1) s[i]=a[len-i-1]-48;
return *this;
}
bign operator=(int num) {char tmp[MAXL]; sprintf(tmp,"%d",num); *this=tmp;return *this;}
bign operator=(const string num) {const char *tmp; tmp=num.c_str(); *this=tmp; return *this;}
bool operator<(const bign &num) const {
if(sign^num.sign) return num.sign;
if(len!=num.len) return len>num.len;
R(i,0,len-1) if(s[i]!=num.s[i])
return sign?(s[i]<num.s[i]):(!(s[i]<num.s[i]));
return !sign;
}
bool operator>(const bign &num) const {return num<*this;}
bool operator<=(const bign &num) const {return !(*this>num);}
bool operator>=(const bign &num) const {return !(*this<num);}
bool operator!=(const bign &num) const {return *this>num||*this<num;}
bool operator==(const bign &num) const {return !(*this!=num);}
bign operator+(const bign &num) const {
if(sign^num.sign) {
bign tmp=sign?num:*this;
tmp.sign=1;
return sign?*this-tmp:num-tmp;
}
bign res;
int tmp=res.len=0;
for(register int i=0;tmp||i<(max(len,num.len));i++) {
int t=s[i]+num.s[i]+tmp;
res.s[res.len++]=t%10;
tmp=t/10;
}
return res;
}
bign operator++() {*this=*this+1;return *this;}
bign operator++(int) {bign old=*this;++(*this);return old;}
bign operator+=(const bign &num) {*this=*this+num;return *this;}
bign operator-(const bign &num) const {
bign b=num,a=*this;
if(!num.sign&&!sign) {b.sign=a.sign=1;return b-a;}
if(!b.sign) {b.sign=1;return a+b;}
if(!a.sign) {a.sign=1;b=bign(0)-(a+b);return b;}
if(a<b) {bign c=(b-a);c.sign=0;return c;}
bign res; res.len=0;
for(int i=0,g=0;i<a.len;i++) {
int x=a.s[i]-g;
if(i<b.len) x-=b.s[i];
if(x>=0) g=0;
else g=1,x+=10;
res.s[res.len++]=x;
}
res.clean();
return res;
}
bign operator*(const bign &num) const {
bign res; res.len=len+num.len;
F(i,0,len-1) F(j,0,num.len-1) res.s[i+j]+=s[i]*num.s[j];
F(i,0,res.len-1) {res.s[i+1]+=res.s[i]/10; res.s[i]%=10;}
res.clean();
res.sign=!(sign^num.sign);
return res;
}
bign operator*(const int num) const {bign a=num,b=*this;return a*b;}
bign operator*=(const bign &num) {*this=*this*num;return *this;}
bign operator/(const bign &num) const {
bign res; res.len=len-num.len+1;
if(res.len<0) {res.len=1;return res;}
bign dis=*this,did=num;//divisor divid
dis.sign=did.sign=1;
int k=res.len-1,j=len-1;
while(k>=0) {
while(!dis.s[j]) j--;
if(k>j) k=j;
char reg[MAXL]; M(reg,0);
R(i,k,j) reg[j-i]=dis.s[i]+'0';
bign die=reg;//dividend
if(die<did) {k--;continue;}
int key=0;
while(did*key<=die) key++;
key--;
res.s[k]=key;
bign tmp=did*key;
F(i,0,k-1) tmp=tmp*10;
dis=dis-tmp;
k--;
}
res.clean();
res.sign=!(sign^num.sign);
return res;
}
bign operator/=(const bign &num) {*this=*this/num;return *this;}
bign operator%(const bign &num) {
bign a=*this,b=num; a.sign=b.sign=1;
bign res,tmp=a/b*b;
res=a-tmp; res.sign=sign;
return res;
}
void clean() {if(len==0)len++; while(len>1&&s[len-1]=='\0')len--;}
bign pow(const bign& num) {bign res=1; for(bign i=0;i<num;i++) res=res*(*this); return res;}
bign fac()const {bign res=1; for(bign i=1;i<=*this;i++) res=res*i; return res;}
bign sqrt()const {
if(*this<0) return -1;
if(*this<=1) return *this;
bign l=0,r=*this,mid;
while(r-l>1) {
mid=(l+r)/2;
if(mid*mid>*this) r=mid;
else l=mid;
}
return l;
}
};