模板集合
建议用标题旁边打开的目录,更清晰明了!
太多了,编辑的时候要找好久,数据结构和图论都搬出去了,下面有链接。离数学搬家也不远了。
好了,数学也搬出去了。
其他
头文件
纯粹方便用
#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;
}