模板集合

建议用标题旁边打开的目录,更清晰明了!

太多了,编辑的时候要找好久,数据结构和图论都搬出去了,下面有链接。离数学搬家也不远了。

好了,数学也搬出去了。

其他

头文件

纯粹方便用
#include<bits/stdc++.h>
using namespace std;
int main(){
	
	
	
	return 0;
}

读入、输出优化(必加!!!)

MINE

模板
namespace io{
	char gc(){
		static char buf[100000],*p1=buf,*p2=buf;
		return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
	}
	int read(){
		int sum=0,f=1;char a=gc();
		while(a<'0' || a>'9'){if(a=='-')f=-1;a=gc();}
		while(a>='0' && a<='9')	sum=sum*10+a-'0',a=gc();
		return sum*f;
	}
	void print(int x){
		if(x<0)	putchar('-'),x=-x;
		if(x>9)	print(x/10);
		putchar(char(48+x%10));
	}
}

一个更好用的版本

点击查看代码
inline char gc(){
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf)
           + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}
template<typename T> inline
void read(T& x) {
    T f = 1, b = 0; char ch = gc();
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = gc();
    } while (ch >= '0' && ch <= '9')
        b *= 10, b += ch - '0', ch = gc();
    x = f * b; return;
}
template<typename T> inline
void print(T x) {
    if (x == 0) return putchar('0'), void();
    if (x < 0) putchar('-'), x = -x;
    int st[129] = {0}, k = 0;
    while (x) st[++k] = x % 10, x /= 10;
    for (int i = k; i; i--) putchar(st[i] + '0');
}

数据结构

图论

字符串

KMP

模板指路

点击查看代码
#include<bits/stdc++.h>
using namespace std;

const int N=1e6+5;
int nxt[N];
char a[N],b[N];

int main(){

	scanf("%s%s",a+1,b+1);
	int n=strlen(a+1),m=strlen(b+1);
	for(int i=2,j=0;i<=m;++i){
		while(j && b[i]!=b[j+1])	j=nxt[j];
		if(b[i]==b[j+1])	++j;
		nxt[i]=j;
	}
	for(int i=1,j=0;i<=n;++i){
		while(j && a[i]!=b[j+1])	j=nxt[j];
		if(a[i]==b[j+1])	++j;
		if(j==m)	cout<<i-m+1<<"\n";
	}
	for(int i=1;i<=m;++i)	cout<<nxt[i]<<" ";

	return 0;
}

字符串哈希

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second

const int p=133331,p2=917120411,p1=1e9+7,N=1e6+5;
pii hs[N],pre[N];
char a[N];
pii get(int l,int r){
	int t1=hs[r].fi-hs[l-1].fi*pre[r-l+1].fi%p1;t1=(t1%p1+p1)%p1;
	int t2=hs[r].se-hs[l-1].se*pre[r-l+1].se%p2;t2=(t2%p2+p2)%p2;
	return mk(t1,t2);
}

signed main(){

	int n,m;
	scanf("%s%lld",a+1,&n);
	m=strlen(a+1);
	pre[0]=mk(1,1);
	for(int i=1;i<=m;++i)	pre[i]=mk(pre[i-1].fi*p%p1,pre[i-1].se*p%p2);
	for(int i=1;i<=m;++i)
		hs[i]=mk((hs[i-1].fi*p%p1+a[i]-'a'+1)%p1,(hs[i-1].se*p%p2+a[i]-'a'+1)%p2);
	while(n--){
		int x,y,c,d;
		cin>>x>>y>>c>>d;
		if(d-c==y-x && get(x,y)==get(c,d))	cout<<"Yes\n";
		else	cout<<"No\n";
	}

	return 0;
}

马拉车(manacher)

点击查看代码
#include<bits/stdc++.h>
using namespace std;

const int N=1.1e7+5;
int len[N<<1];
char a[N],s[N<<1];

int main(){

	scanf("%s",a+1);
	int n=strlen(a+1),m=1;
	s[0]='-',s[1]='|';
	for(int i=1;i<=n;++i)	s[++m]=a[i],s[++m]='|';
	int ans=0;
	for(int i=1,j=0,ce=0;i<=m;++i){
		if(i<=j)	len[i]=min(j-i+1,len[ce*2-i]);
		while(s[i+len[i]]==s[i-len[i]])	++len[i];
		if(len[i]+i-1>j)	j=len[i]+i-1,ce=i;
		ans=max(ans,len[i]-1);
	}
	cout<<ans;

	return 0;
}

AC 自动机

模板指路

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define se second
#define fi first

const int N=2e6+5;
struct node{
	int end,fail,s[26];
};
node a[N];
int n,co;

void insert(string s){
	int u=0;
	for(int i=0;i<s.size();++i){
		if(!a[u].s[s[i]-'a'])	a[u].s[s[i]-'a']=++co;
		u=a[u].s[s[i]-'a'];
	}
	a[u].end++;
}
void get_fail(){
	queue<int> q;
	for(int i=0;i<26;++i)
		if(a[0].s[i])
			q.push(a[0].s[i]),a[a[0].s[i]].fail=0;
	while(q.size()){
		int x=q.front();q.pop();
		for(int i=0;i<26;++i){
			if(a[x].s[i])
				a[a[x].s[i]].fail=a[a[x].fail].s[i],
				q.push(a[x].s[i]);
			else	a[x].s[i]=a[a[x].fail].s[i];
		}
	}
}
int fi(string s){
	int res=0,u=0;
	for(int i=0;i<s.size();++i){
		u=a[u].s[s[i]-'a'];
		for(int j=u;j && a[j].end!=-1;j=a[j].fail)
			res+=a[j].end,a[j].end=-1;
	}
	return res;
}

int main(){
	
	cin>>n;
	for(int i=1;i<=n;++i){string s;cin>>s;insert(s);}
	get_fail();
	string s;cin>>s;
	printf("%d",fi(s));
	
	return 0;
}

数学

基础算法

高精度

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+25,p=1000;
struct Lint{
	int a[N],len;
	Lint(){len=1;memset(a,0,sizeof a);}
	Lint(string s){
		int tmp=0,c=1,n=s.size();len=0;
		for(int i=n-1;i>=0;--i){
			tmp=tmp+(s[i]-'0')*c,c*=10;
			if(c==p){a[++len]=tmp;c=1,tmp=0;}
		}
		if(tmp||!len)a[++len]=tmp;
	}
	Lint(int x){do{a[++len]=x%p,x/=p;}while(x);}
	void print(){
		cout<<a[len];
		for(int i=len-1;i;--i){
			int c=10;
			while(a[i]*c<p&&c<p)cout<<'0',c*=10;
			cout<<a[i];
		}
		cout<<'\n';
	}
	bool operator<(Lint b){
		if(len!=b.len)return len<b.len;
		for(int i=len;i;--i)if(a[i]!=b.a[i])return a[i]<b.a[i];
		return 0;
	}
	Lint operator+(Lint b){
		Lint tmp;tmp.len=max(len,b.len);
		for(int i=1;i<=tmp.len;++i){
			tmp.a[i]+=a[i]+b.a[i];
			tmp.a[i+1]=tmp.a[i]/p,tmp.a[i]%=p;
		}
		if(tmp.a[tmp.len+1])++tmp.len;
		return tmp;
	}
	Lint operator-(Lint b){
		Lint tmp;tmp.len=len;
		for(int i=1;i<=len;++i){
			if(b.len<i)b.a[i]=0;
			tmp.a[i]=a[i]-b.a[i];
			if(tmp.a[i]<0)tmp.a[i]+=p,a[i+1]--;
		}
		while(tmp.len>1&&tmp.a[tmp.len]==0)--tmp.len;
		return tmp;
	}
	Lint operator*(Lint b){
		Lint tmp;tmp.len=len+b.len-1;
		for(int i=1;i<=len;++i)
			for(int j=1;j<=b.len;++j)tmp.a[i+j-1]+=a[i]*b.a[j];
		for(int i=1;i<=tmp.len;++i)tmp.a[i+1]+=tmp.a[i]/p,tmp.a[i]%=p;
		while(tmp.a[tmp.len+1])++tmp.len,tmp.a[tmp.len+1]+=tmp.a[tmp.len]/p,tmp.a[tmp.len]%=p;
		return tmp;
	}
};
signed main(){

	string s;Lint ans=1;
	while(cin>>s){ans=ans*s;}
	ans.print();

	return 0;
}

快速幂

点击查看代码
inline int ksm(int x,int y,int p){
	int res=1;
	while(y){if(y&1)res=res*x%p;x=x*x%p,y>>=1;}
	return res;
}
posted @ 2022-08-28 22:22  _yolanda  阅读(242)  评论(1编辑  收藏  举报