模板大全

模板大全

写着写着放弃了(实则是退役了)

快读快写

inline int read() {
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return f*x;
}
template<typename F>
inline void write(F x, char ed = '\n')
{
	static short st[30];short tp=0;
	if(x<0) putchar('-'),x=-x;
	do st[++tp]=x%10,x/=10; while(x);
	while(tp) putchar('0'|st[tp--]);
	putchar(ed);
}

数学

看 :

算数基本定理

模运算(余数)

$amodP=a-\left\lfloor\dfrac{a}{P}\right\rfloor *P $$

扩展欧几里得

int x,y;
int exgcd(int a,int b) {
	if(!b) {x=1,y=0;return a;}
	int ans=exgcd(b,a%b),tmp=x;
	x=y;y=tmp-a/b*y;
	return ans;
}
void exgcd(ll a,ll b){
	if(!b) {x=1,y=0;return;}
	exgcd(b,a%b);
	ll t=x;
	x=y;
	y=t-(a/b)*y;
}

最小整数解 $$ x=(x% b+b)%b $$

逆元

费马小定理
qpow(x,p-2);
线性递推
inv[1]=1;
    for(int i=2;i<=n;i++) 
        inv[i]=(ll)p-(p/i)*inv[p%i]%p;

线性筛

    for(int i=2;i<=n;i++){
        if(!mindiv[i]) mindiv[i]=prime[++prime[0]]=i;
        for(int j=1;j<=prime[0]&&i*prime[j]<=n&&prime[j]<=mindiv[i];j++)
            mindiv[i*prime[j]]=prime[j];
    }

筛phi

void PHI(int x){
    phi[1]=1;
    for(int i=2;i<=x;i++){
        if(!mindiv[i]) mindiv[i]=p[++p[0]]=i,phi[i]=i-1;
        for(int j=1;j<=p[0]&&i*p[j]<=x;j++){
            mindiv[i*p[j]]=p[j];
            if(i%p[j]==0){
                phi[i*p[j]]=phi[i]*p[j];
                break;
            }else phi[i*p[j]]=phi[i]*phi[p[j]];
        }
    }
}

筛约数个数,约数和

https://blog.csdn.net/controlbear/article/details/77527115

#include<cstdio>
#include<algorithm>
typedef long long ll;
inline int gi(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
const int N=1000001;
int prime[N],d[N],f[N];
bool mindiv[N];
int main(){
    int n=gi();
    for(int i=1;i<=n;++i) d[i]=1;
    for(int i=2;i<=n;++i){
        if(!mindiv[i]) prime[++prime[0]]=i,d[i]=2,f[i]=1;
        for(int j=1;i*prime[j]<=n&&j<=prime[0];++j){
            mindiv[i*prime[j]]=1;
            if(i%prime[j]==0){
                f[i*prime[j]]=f[i]+1;
                d[i*prime[j]]=d[i]/(f[i]+1)*(f[i*prime[j]]+1);
                break;
            }
            f[i*prime[j]]=1;
            d[i*prime[j]]=d[i]*d[prime[j]];
        }
    }
    ll ans=0;
    for(int i=1;i<=n;++i) ans+=d[i];
    printf("%lld\n",ans);
    return 0;
}
sd[1]=1;
for(int i=2;i<=n;++i){
    if(!mindiv[i]) prime[++prime[0]]=i,sd[i]=sp[i]=i+1;
    for(int j=1;i*prime[j]<=n&&j<=prime[0];++j){
        mindiv[i*prime[j]]=1;
        if(i%prime[j]==0){
            sp[i*prime[j]]=sp[i]*prime[j]+1;
            sd[i*prime[j]]=sd[i]/sp[i]*sp[i*prime[j]];
            break;
        }
        sp[i*prime[j]]=1+prime[j];
        sd[i*prime[j]]=sd[i]*sd[prime[j]];
    }
}

生成质数的范围是[m,n] (1 <= m <= n <= 10^9, n-m<=1000000)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 10000003
using namespace std;
int pd[N],prime[N],T,l,r,vis[N];//prime[0]
void init(){
	pd[1]=1;
	for(int i=2;i<=100000;i++){
		if(!pd[i])prime[++prime[0]]=i;
		for(int j=1;j<=prime[0];j++){
			if(i*prime[j]>100000)break;
			pd[prime[j]*i]=1;
			if(i%prime[j]==0)break;
		}
	}
}
int main(){
	init();
	scanf("%d",&T);
	for(int i=1;i<=T;i++){
		scanf("%d%d",&l,&r);
		for(int j=1;j<=prime[0];j++){
			int t=(l-1)/prime[j]+1;
			if(t<=1)t=2;
			for(int k=t*prime[j];k<=r;k+=prime[j])
				vis[k-l+1]=i;
		}
		for(int j=1;j<=r-l+1;j++)
			if(vis[j]!=i && j+l-1!=1)printf("%d\n",j+l-1);
		puts("");
	} 
	return 0;
} 

矩阵快速幂

#include <cstdio> 
#include <cstring> 
#include <iostream> 
using namespace std;
typedef long long ll;
#define maxn 105
#define mod 1000000007
inline ll read(){
    ll f=1,x=0; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
    return f*x;
}
ll k;
int n;
struct jz{
	ll a[maxn][maxn];     //一定要用long long存矩阵,否则在过程中会爆掉
	jz(){
		memset(a,0,sizeof a);
	}
	inline void build(){     //建造单位矩阵
		for(int i=1;i<=n;++i)a[i][i]=1;
	}
}a,ans;
jz operator * (const jz &x,const jz &y){     //重载运算符
	jz z;
	for(int k=1;k<=n;++k)
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
	return z;
}

int main(){
	n=read();k=read();
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			a.a[i][j]=read();
	ans.build();
	do{     
		if(k&1)ans=ans*a;
		a=a*a;
		k>>=1;
	}while(k);
	for(int i=1;i<=n;putchar('\n'),++i)
		for(int j=1;j<=n;++j)
			printf("%d ",ans.a[i][j]);
	return 0;
}

图论

dp

区间dp

大概的板子——Q-key

一定要注意小的合并成大的中间需要的贡献

for(int len=1;len<=n;len++)
    for(int l=1;l<=(n<<1)&&l+len<=(n<<1);l++) {
        int r=l+len;
        f[l][r]=0x3f3f3f3f;//Q
        for(int k=l;k<r;k++) {
            f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]+sum[l][r]);
            g[l][r]=max(g[l][r],g[l][k]+g[k+1][r]+sum[l][r]);
        }
    }
posted @ 2020-12-08 14:14  ke_xin  阅读(201)  评论(0编辑  收藏  举报