long long qpow(long long a,long long b,int mod)
{
long long res=;
while (b)
{
if (b&) res=res*a%mod;
a=a*a%mod;
b>>=;
}
return res%mod;
}

快速幂

 const int mod1=;
const int mod2=;
const int mod3=;
bool show[mod3];
int hash(string a)
{
long long val=;
int ha1=,ha2=;
int len=a.length();
for(register int i=len-;i>-;i--)
{
ha1+=a[i]*val;
ha1%=mod1;
ha2+=a[i]*val;
ha2%=mod2;
val*=;
if(val > ) val=;
}
return (long long)ha1*ha2%mod3;
}

字符串哈希

 int k,n,m,cnt,sum,ai,bi,ci,head[],dis[],vis[];
struct Edge
{
int v,w,next;
}e[];
void add(int u,int v,int w)
{
e[++k].v=v;
e[k].w=w;
e[k].next=head[u];
head[u]=k;
}
typedef pair <int,int> pii;
priority_queue <pii,vector<pii>,greater<pii> > q;
int Prim()
{
memset(dis,,sizeof(dis));
memset(head,-,sizeof(head));
dis[]=;
q.push(make_pair(,));
while(!q.empty()&&cnt<n)
{
int d=q.top().first,u=q.top().second;
q.pop();
if(vis[u]) continue;
cnt++;
sum+=d;
vis[u]=;
for(R i=head[u];i!=-;i=e[i].next)
if(e[i].w<dis[e[i].v])
dis[e[i].v]=e[i].w,q.push(make_pair(dis[e[i].v],e[i].v));
}
if (cnt==n) return sum;
return -;

Prim

 struct Edge
{
int x,y,z;
}e[];
int n,m,u,v,fu,fv,cnt,ans;
int fa[];
bool cmp(Edge a,Edge b){return a.z < b.z || (a.z==b.z && a.x<b.x);}
int find(int x){return x == fa[x]?x:fa[x]=find(fa[x]);}
void kruskal()
{
for(int i=;i<=m;i++) fa[i] = i;
for(int i=;i<=n;i++)
{
u = e[i].x;
v = e[i].y;
fu = find(u);
fv = find(v);
if(fu != fv)
{
fa[fu] = fv;
ans += e[i].z;
cnt++;
}
if(cnt == m-) break;
}
if (ans) return ans;
return -'
}

Kruskal(最后return,";"写成"'"了,请自行改过来)

 #ifndef DS
#define DS
template <unsigned const long long maxn=>
class i_Ds
{
typedef long long X;
X s[maxn],height[maxn];
typedef X inte;
public:
void init(){for (inte i=;i<maxn;i++) s[i]=i,height[i]=;}
i_Ds(){init();}
X find(X x) {if (x!=s[x]) s[x]=find(s[x]);return s[x];}
void _union(X x,X y)
{
x=find(x);y=find(y);
if (height[x]==height[y]) height[x]++,s[y]=x;
else if(height[x]<height[y]) s[x]=y;
else s[y]=x;
}
inte js(inte b,inte n) {inte ans=;for (inte i=b;i<n;i++)if (s[i]==i) ++ans;return ans;}
inte js(const inte n=maxn){inte ans=;for (inte i=;i<n;i++)if (s[i]==i) ++ans;return ans;}
};
#endif

并查集(路径压缩+按秩合并)

 int prime[maxn];
int visit[maxn];
void Prime()
{
memset(visit,,sizeof visit);
memset(prime,,sizeof prime);
for (int i=;i<=maxn;i++)
{
if (!visit[i]) prime[++prime[]]=i;
for (int j=;j<=prime[]&&i*prime[j]<=maxn;j++)
{
visit[i*prime[j]]=;
if ((!i%prime[j])) break;
}
}
}

线性筛素数(欧拉筛)

 void qsort(int a[],int l,int r)
{
int i=l,j=r,mid=a[(l+r)/];
do
{
while (a[i]<mid) i++;
while (a[j]>mid) j--;
if (i<=j)
{
int tmp=a[i];a[i]=a[j];a[j]=tmp;
i++;j--;
}
}while(i<=j);
if (l<j) qsort(a,l,j);
if (i<r) qsort(a,i,r);
}

快排

 //用洛谷P3865做示范
#include<cstdio>
#define max(a,b) (a>b?a:b)
using namespace std;
int data[]={};
int init[]={-};
int st[][]={};
int main()
{
int N=,M=;
scanf("%d%d",&N,&M);
for(int i=;i<=N;i++)
{
scanf("%d",&data[i]);
init[i]=init[i/]+;
}
for(int i=;i<=N;i++) //init begin.
st[i][]=data[i];
for(int i=;i<=init[N];i++)
for(int j=;j+(<<i)-<=N;j++)
st[j][i]=max(st[j][i-],st[j+(<<(i-))][i-]);//init end.
int Left=,Right=;
while(M--)
{
scanf("%d%d",&Left,&Right);
int Length=init[Right-Left+];
printf("%d\n",max(st[Left][Length],st[Right-(<<(Length))+][Length]));
}
return ;
}

ST表

 if (所有石子个数异或得到的数字==) cout<<"先手必败“;
else cout<<"先手必胜“;

Nim游戏

 void exgcd(int a,int b,int& x,int& y)
{
if (!b){x=,y=;return ;}
exgcd(b,a%b);
int t=x;
x=y,y=t-a/b*y;
}

Exgcd

 //前置exgcd
int inv(int k,int p)
{
int x,y;
exgcd(k,p,x,y);
return (x%p+p)%p;
}

乘法逆元

 const int N = ; //设置数组的大小
bool line[N][N]; //记录连接x和y的边,如果i和j之间有边则为1,否则为0
int result[N]; //记录当前与y节点相连的x的节点:i未加入匹配时为link[i]==0
bool used[N]; //记录y中节点是否使用
int k, m, n;
bool found(int x)
{
for (int i = ; i <= n; i++)
{
if (line[x][i] && !used[i])
{
used[i] = true;
if (result[i] == || found(result[i]))
{
result[i] = x;
return true;
}
}
}
return false;
}
int main()
{
int x, y;
printf("请输入相连边的数量k:\n");
while (scanf("%d", &k) && k)
{
printf("请输入二分图中x和y中点的数目:\n");
scanf("%d %d", &m, &n);
memset(line, , sizeof(line));
memset(result, , sizeof(result));
for (int i = ; i < k; i++)
{
printf("请输入相连边的两个点:\n");
scanf("%d %d", &x, &y);
line[x][y] = ;
}
int sum = ;
for (int i = ; i <= m; i++)
{
memset(used, , sizeof(used));
if (found(i)) sum++;
}
printf("%d\n", sum);
}
return ;
}

[邻接矩阵]匈牙利算法

 //P3379示范
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Edge
{
int Length,Next;
}ed[];
int start[],tot;
void Add_Edge(int x,int y)
{
ed[++tot].Length=y;
ed[tot].Next=start[x];
start[x]=tot;
}
int depth[], f[][], lg[];
void dfs(int now,int pre)
{
f[now][]=pre;
depth[now]=depth[pre]+;
for (int i=;i<=lg[depth[now]];++i)
f[now][i]=f[f[now][i-]][i-];
for (int i=start[now];i!=;i=ed[i].Next)
if(ed[i].Length!=pre) dfs(ed[i].Length,now);
}
int LCA(int x, int y)
{
if (depth[x]<depth[y]) swap(x,y);
while (depth[x]>depth[y])
x=f[x][lg[depth[x]-depth[y]]-];
if (x==y) return x;
for (int k=lg[depth[x]]-;k>=;--k)
if (f[x][k]!=f[y][k])
x=f[x][k],y=f[y][k];
return f[x][];
}
int main()
{
int n,m,s;
scanf("%d%d%d", &n, &m, &s);
for (int i=;i<=n-;++i)
{
int x,y;
scanf("%d%d",&x,&y);
Add_Edge(x,y);
Add_Edge(y,x);
}
for(int i=;i<=n;++i)
lg[i]=lg[i-]+(<<lg[i-]==i);
dfs(s,);
for (int i=;i<=m;++i)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
return ;
}

LCA

 #include<iostream>
#include<cstring>
#innclude<cmath>
struct Trie
{
int ch[maxn][maxsize];
int val[maxn];
int sz;
Trie()
{
sz=;
val[]=;
memset(ch[],,sizeof ch[]);
}
void clear()
{
sz=;
val[]=;
memset(ch[],,sizeof ch[]);
}
int idx(char c){return c-'a';}
void insert(const char *s,int v=)
{
int u=,n=strlen(s);
for (int i=;i<n;i++)
{
int c=idx(s[i]);
if (ch[u][c]==)
{
memset(ch[sz],,sizeof ch[sz]);
val[sz]=;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
}
int find(const char *s)
{
int u=,n=strlen(s);
for (int i=;i<n;i++)
{
int c=idx(s[i]);
if (ch[u][c]==) return -;
u=ch[u][c];
}
return val[u];
}
void del(const char *s)
{
int u=,n=strlen(s);
for (int i=;i<n;i++)
{
int c=idx(s[i]);
if (ch[u][c]==) return ;
u=ch[u][c];
}
val[u]=;
}
};

Trie

 struct point
{
int hao;
ll dis;
bool friend operator <(point a,point b){return a.dis>b.dis;}
};
priority_queue<point>q;
void dij()
{
point st;
st.hao=s;
st.dis=;
q.push(st);
int has=;
while ((has!=n)&&(!q.empty()))
{
point now=q.top();
q.pop();
if (vis[now.hao]) continue;
has++;
vis[now.hao]=;
dis[now.hao]=now.dis;
for (int i=head[now.hao];i;i=bian[i].nxt)
{
int y=bian[i].to;
if (!vis[y])
{
point last;
last.hao=y;
last.dis=now.dis+bian[i].val;
q.push(last);
}
}
}
}

Dijkstra+堆优化

 //初始化
for (i=;i<=n;i++)
for (j=;j<=n;j++)
e[i][j]=(i==j)?:inf;
//核心
for(k=;k<=n;k++)
for(i=;i<=n;i++)
for(j=;j<=n;j++)
e[i][j]=max(e[i][j],e[i][k]+e[k][j]);

Floyd

 int Kmp(char* s, char* p)
{
int i=,j=;
int sLen=strlen(s);
int pLen=strlen(p);
while (i<sLen&&j<pLen)
{
if (j==-||s[i]==p[j]) i++,j++;
else j=next[j];
}
if (j==pLen) return i-j;
else return -;
}

KMP

 char s[];
char s_new[]
int p[];
int Init()
{
int len=strlen(s);
s_new[]='$';
s_new[]='#';
int j=;
for(int i=;i<len;i++)
{
s_new[j++]=s[i];
s_new[j++]='#';
}
s_new[j]='\0';
return j;
}
int Manacher()
{
int len=Init();
int max_len=-;
int id;
int mx=;
for(int i=;i<=len;i++)
{
if(i<mx)
p[i]=min(p[*id-i],mx-i);
else p[i]=;
while (s_new[i-p[i]]==s_new[i+p[i]]) p[i]++;
if(mx<i+p[i]) id=i,mx=i+p[i];
max_len=max(max_len,p[i]-);
}
return max_len;
}

Manacher(马拉车)

 //最小表示法
int getMin(char *str)
{
int i=,j=,k=;
int slen=strlen(str);
while (i<slen&&j<slen&&k<slen)
{
int tmp=str[(i+k)%slen]-str[(j+k)%slen];
if (tmp==) k++;
else
{
if (tmp>) i=i+k+;
else j=j+k+;
if (j==i) j++;
k=;
}
}
return min(i,j);
}
//最大表示法
int getMax(char *str)
{
int i=,j=,k=;
int slen=strlen(str);
while (i<slen&&j<slen&&k<slen)
{
int tmp=str[(i+k)%slen]-str[(j+k)%slen];
if (tmp==) k++;
else
{
if (tmp>) j=j+k+;
else i=i+k+;
if (i==j) j++;
k=;
}
}
return min(i,j);
}

最小(大)表示法

 //hdu2222为例
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+;
const int MAX=;
int cnt;
struct node
{
node *next[];
node *fail;
int sum;
};
node *root;
char key[];
node *q[MAX];
int head,tail;
node *newnode;
char pattern[maxn];
int N;
void Insert(char *s)
{
node *p = root;
for(int i = ; s[i]; i++)
{
int x = s[i] - 'a';
if(p->next[x] == NULL)
{
newnode=(struct node *)malloc(sizeof(struct node));
for(int j=;j<;j++) newnode->next[j] = ;
newnode->sum = ;newnode->fail = ;
p->next[x]=newnode;
}
p = p->next[x];
}
p->sum++;
}
void build_fail_pointer()
{
head = ;
tail = ;
q[head] = root;
node *p;
node *temp;
while(head < tail)
{
temp = q[head++];
for(int i = ; i <= ; i++)
{
if(temp->next[i])
{
if(temp == root)
{
temp->next[i]->fail = root;
}
else
{
p = temp->fail;
while(p)
{
if(p->next[i])
{
temp->next[i]->fail = p->next[i];
break;
}
p = p->fail;
}
if(p == NULL) temp->next[i]->fail = root;
}
q[tail++] = temp->next[i];
}
}
}
}
void AC(char *ch)
{
node *p = root;
int len = strlen(ch);
for(int i = ; i < len; i++)
{
int x = ch[i] - 'a';
while(!p->next[x] && p != root) p = p->fail;
p = p->next[x];
if(!p) p = root;
node *temp = p;
while(temp != root)
{
if(temp->sum >= )
{
cnt += temp->sum;
temp->sum = -;
}
else break;
temp = temp->fail;
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
root=(struct node *)malloc(sizeof(struct node));
for(int j=;j<;j++) root->next[j] = ;
root->fail = ;
root->sum = ;
scanf("%d",&N);
getchar();
for(int i = ; i <= N; i++)
{
gets(key);
Insert(key);
}
gets(pattern);
cnt = ;
build_fail_pointer();
AC(pattern);
printf("%d\n",cnt);
}
return ;
}

AC自动机

 for(int i=;i<=n;i++)
for(int j=m;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

0-1背包

 for(int i=;i<=n;i++)
for(int j=w[i];j<=m;j++)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);

完全背包

 for(int i=;i<=n;i++)
{
int x,y,s,t=;
scanf("%d%d%d",&x,&y,&s); //重量,价值,数量
while (s>=t){v[++n1]=x*t;w[n1]=y*t;s-=t;t*=;}
v[++n1]=x*s;
w[n1]=y*s;
}
for(int i=;i<=n1;i++)
for(int j=m;j>=v[i];j--)
dp[j]=max(dp[j],f[dp-v[i]]+w[i]);

多重背包(二进制分组)

 //洛谷P1855为例
#include<cstdio>
#include<iostream>
using namespace std;
int n,M,T,dp[][];
int m[],t[];
int main()
{
scanf("%d%d%d",&n,&M,&T);
for(int i=;i<=n;i++)
{
scanf("%d%d",&m[i],&t[i]);
for(int j=M;j>=m[i];j--)
for(int k=T;k>=t[i];k--)
dp[j][k]=max(dp[j][k],dp[j-m[i]][k-t[i]]+);
}
printf("%d",dp[M][T]);
return ;
}

二维费用背包

 //洛谷P1757为例
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 100000
#define sc scanf
#define pr printf
#define re register
using namespace std;
int n,m,ans,mm;
int tong[][],f[maxn],w[maxn],v[maxn],c[maxn],num[maxn];
int main()
{
bool cp=true;
cin>>m>>n;
if (m!=||n!=) cp=false;
for(re int i=;i<=n;i++)
{
cin>>w[i]>>v[i]>>c[i];
if (w[i]!=||v[i]!=||c[i]!=i) cp=false;
num[c[i]]++;
if(num[c[i]]==)
mm++;
tong[c[i]][num[c[i]]]=i;
}
if (cp){cout<<;return ;}
for (int k=;k<=mm;k++)
for (int j=m;j>=;j--)
for (int i=;i<=num[k];i++)
if(j-w[tong[k][i]]>)
f[j]=max(f[j],f[j-w[tong[k][i]]]+v[tong[k][i]]);
cout<<f[m];
return ;
}

分组背包

 //以"NOIP2006金明的预算方案"为例
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m;
int f[],h[];
struct node{int v,p,q;}a[];
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&a[i].v,&a[i].p,&a[i].q);
a[i].p*=a[i].v;
}
for(int i=;i<=m;i++)
if(!a[i].q)
{
for(int j=;j<a[i].v;j++)
h[j]=;
for(int j=a[i].v;j<=n;j++)
h[j]=f[j-a[i].v]+a[i].p;
for(int j=;j<=m;j++)
if(a[j].q==i)
for(int k=n;k>=a[i].v+a[j].v;k--)
h[k]=max(h[k],h[k-a[j].v]+a[j].p);
for(int j=a[i].v;j<=n;j++)
f[j]=max(f[j],h[j]);
}
printf("%d\n",f[n]);
return ;
}

有依赖的背包

 //它为何在这?因为SPFA本来在前面,然后代码失效,只好搬到这
int dis[MAXN];
bool vis[MAXN];
void SPFA(int s)
{
for(int i=;i<=MAXN;i++){dis[i]=INF;vis[i]=true;}
dis[s]=;
queue<int> q;
q.push(s);
vis[s]=false;
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=true;
for(int i=head[u];~i;i=ed[i].next)
{
int v=ed[i].to;
if(dis[u]+ed[i].w<dis[v])
{
dis[v]=dis[u]+ed[i].w;
if(vis[v]){q.push(v);vis[v]=false;}
}
}
}
}

SPFA

 #include<iostream>
#include<sstream>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
using namespace std;
struct Wint:vector<int>
{
Wint(int n=)
{
push_back(n);
check();
}
Wint& check()
{
while(!empty()&&!back())pop_back();
if(empty())return *this;
for(int i=; i<size(); ++i)
{
(*this)[i]+=(*this)[i-]/;
(*this)[i-]%=;
}
while(back()>=)
{
push_back(back()/);
(*this)[size()-]%=;
}
return *this;
}
};
istream& operator>>(istream &is,Wint &n)
{
string s;
is>>s;
n.clear();
for(int i=s.size()-; i>=; --i)n.push_back(s[i]-'');
return is;
}
ostream& operator<<(ostream &os,const Wint &n)
{
if(n.empty())os<<;
for(int i=n.size()-; i>=; --i)os<<n[i];
return os;
}
bool operator!=(const Wint &a,const Wint &b)
{
if(a.size()!=b.size())return ;
for(int i=a.size()-; i>=; --i)
if(a[i]!=b[i])return ;
return ;
}
bool operator==(const Wint &a,const Wint &b){return !(a!=b);}
bool operator<(const Wint &a,const Wint &b)
{
if(a.size()!=b.size())return a.size()<b.size();
for(int i=a.size()-; i>=; --i)
if(a[i]!=b[i])return a[i]<b[i];
return ;
}
bool operator>(const Wint &a,const Wint &b){return b<a;}
bool operator<=(const Wint &a,const Wint &b){return !(a>b);}
bool operator>=(const Wint &a,const Wint &b){return !(a<b);}
Wint& operator+=(Wint &a,const Wint &b)
{
if(a.size()<b.size())a.resize(b.size());
for(int i=; i!=b.size(); ++i)a[i]+=b[i];
return a.check();
}
Wint operator+(Wint a,const Wint &b)
{
return a+=b;
}
Wint& operator-=(Wint &a,Wint b)
{
if(a<b) swap(a,b);
for(int i=; i!=b.size(); a[i]-=b[i],++i)
if(a[i]<b[i])
{
int j=i+;
while(!a[j])++j;
while(j>i)
{
--a[j];
a[--j]+=;
}
}
return a.check();
}
Wint operator-(Wint a,const Wint &b){return a-=b;}
Wint operator*(const Wint &a,const Wint &b)
{
Wint n;
n.assign(a.size()+b.size()-,);
for(int i=; i!=a.size(); ++i)
for(int j=; j!=b.size(); ++j)
n[i+j]+=a[i]*b[j];
return n.check();
}
Wint& operator*=(Wint &a,const Wint &b){return a=a*b;}
Wint divmod(Wint &a,const Wint &b)
{
Wint ans;
for(int t=a.size()-b.size(); a>=b; --t)
{
Wint d;
d.assign(t+,);
d.back()=;
Wint c=b*d;
while(a>=c)
{
a-=c;
ans+=d;
}
}
return ans;
}
Wint operator/(Wint a,const Wint &b){return divmod(a,b);}
Wint& operator/=(Wint &a,const Wint &b){return a=a/b;}
Wint& operator%=(Wint &a,const Wint &b){divmod(a,b);return a;}
Wint operator%(Wint a,const Wint &b){return a%=b;}
Wint pow(const Wint &n,const Wint &k)
{
if(k.empty())return ;
if(k==)return n*n;
if(k.back()%)return n*pow(n,k-);
return pow(pow(n,k/),);
}

百度百科-高精

 namespace IO
{
template<typename T>
inline void read(T &x)
{
x=;
int f=;
char ch=getchar();
while(!(ch>=''&&ch<='')){f|=(ch=='-');ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+(ch^);ch=getchar();}
x=f?-x:x;
}
template<typename T>
inline void write(T x)
{
if(x<) {putchar('-');x=-x;}
if(x>=) write(x/);
putchar(x%+'');
}
}

快读快输

 //效果好
#pragma GCC diagnostic error "-std=c++14"
#pragma GCC target("avx")
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
//效果不太好
#pragma GCC diagnostic error "-std=c++14"
#pragma GCC target("avx")
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")

极致优化

 void getphi()
{
int i,j;
phi[]=;
for (i=;i<=N;i++)
{
if (!mark[i]) {prime[++tot]=i;phi[i]=i-;}
for (j=;j<=tot;j++)
{
if(i*prime[j]>N) break;
mark[i*prime[j]]=;
if (i%prime[j]==){phi[i*prime[j]]=phi[i]*prime[j];break; }
else phi[i*prime[j]]=phi[i]*(prime[j]-);
}
}
}

线性筛欧拉函数

 #include<cstdio>
struct node
{
int data;
node* lchild;
node* rchild;
};
node* newNode(int v)
{
node* Node=new node;
Node->data=v;
Node->lchild=Node->rchild=NULL;
return Node;
}
void insert(node* &root,int x)
{
if(root==NULL){root=newNode(x);return;}
if(x==root->data) return;
else if(x<root->data) insert(root->lchild,x);
else insert(root -> rchild,x);
}
node* Create(int data[],int n)
{
node* root=NULL;
for(int i=;i<n;i++) insert(root,data[i]);
return root;
}
node* findMax(node* root)
{
while(root->rchild!=NULL){root=root->rchild;}
return root;
}
node* findMin(node* root)
{
while(root->lchild!=NULL) root=root->lchild;
return root;
}
void deleteNode(node* &root,int x){
if(root == NULL) return;
if(root->data==x)
{
if(root->lchild==NULL&&root->rchild==NULL) root=NULL;
else if(root->lchild!=NULL)
{
node* pre=findMax(root->lchild);
root->data=pre->data;
deleteNode(root->lchild,pre->data);
}
else
{
node* post=findMin(root->rchild);
root->data=post->data;
deleteNode(root->rchild,post->data);
}
}
else if (root->data>x) deleteNode(root->lchild,x);
else deleteNode(root->rchild,x);
}

BST(二叉搜索树&二叉排序树)

 #include<iostream>
using namespace std;
typedef unsigned long long ull;
ull fact[]={,,,,,,,,,,,,,,};
int A[];
int main()
{
int rank=,s;
int N;
cin>>N;
for (int i=;i<N;i++) cin>>A[i];
for(int i=;i<=N;i++)
{
int s=;
for (int j=i+;j<=N;j++) s+=(A[j]<A[i]);
rank+=s*fact[N-i];
}
cout<<rank;
return ;
 typedef unsigned long long ull;
const ull fact[]={,,,,,,,,,,,,,,,};
ull Cantor(int n,int a[])
{
ull ans=;
for (int i=;i<n;i++)
{
int x=;
for(int j=i+;j<n;j++)
if (a[j]<a[i]) ++x;
ans+=x*fact[n-i-];
}
return ans+;
}

康托展开

 typedef unsigned long long ull;
const ull fac[]={,,,,,,,,,,,,,,,};
void CantorReverse(long long r,int len,int a[]) //康托展开逆运算,结果在a中
{
r--;
int vis[]={};
for(int i=;i<=len;i++)
{
long long tp=r/fac[len-i];
r-=tp*fac[len-i];
int j;
for(j=;j<=len;j++)
if(!vis[j]){if(!tp) break;--tp;}
vis[j]=;
a[i]=j;
}
}

康托展开逆运算

 int binarySearch(int list[],int left,int right,int number)
{
if(list==NULL) return -;
int index=;
int mid=(right+left)/;
if(left>right)
return -;
if(number==list[mid])
{
index=mid;
return index;
}
else if(number>list[mid]) binarySearch(list,mid+,right,number);
else binarySearch(list,left,mid-,number);
}

二分查找(递归)

 int binarySearch(int list[],int left,int right,int number)
{
if(list==NULL) return -;
while(left<right)
{
int mid=(right+left)/;
if (list[mid] == number) return mid;
else if (number > list[mid]) left=mid+;
else if (number < list[mid]) right=mid-;
}
return -;
}

二分查找(循环)

 int sum[*+];
int lowbit(int x) {return x&(-x);}
inline void add(int x,int c){while (x<=n) {sum[x]+=c;x+=lowbit(x);}}
inline int query(int x)
{
int ans=;
while (x>)
{
ans+=sum[x];
x-=lowbit(x);
}
return ans;
}
inline void Make(int a[],const int n)
{
int pre[N];
pre[]=a[];
for (int i=;i<=n;i++) pre[i]=pre[i-]+a[i];
for (int i=;i<=n;i++) sum[i]=pre[i]-pre[i-lowbit(i)];
}
inline int SectionSum(int x,int y){return query(y)-query(x-);}

树状数组

 dp[]=;
for (int =;i<n;i++)
{
dp[i]=;
for (int j=;j<i;j++)
if (x[i]>x[j]&&dp[j]+>dp[i]) dp[i]=dp[j]+;
}
for (int i=max_len=;i<n;i++)
max_len=max(max_len,dp[i]);

LIS

 int len_a=a.size(),len_b=b.size();
for(int i=;i<len_a;i++)
for(int j=;j<len_b;j++)
if (a.at(i)==b.at(j)) dp[i+][j+]=dp[i][j]+;
else dp[i+][j+]=max(dp[i+][j],dp[i][j+]);
cout<<dp[len_a][len_b];

LCS

 //i1,i2为两序列,n,m为序列长度
for (int a=;a<=m;a++)
{
int Max();
for (int b=;b<=n;b++)
{
if (i1[a]>i2[b]&&dp[a-][b]>Max) Max=dp[a-][b];
if (i1[a]!=i2[b]) dp[a][b]=dp[a-][b];
if (i1[a]==i2[b]) dp[a][b]=Max+;
}
}

LCIS

 大根堆:priority_queue<DataType> Name;

 小根堆:priority_queue<DataType,vector<DataType>,greater<DataType> > Name;

STL优先队列模板

 #include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn=;
const int INF=0x3f3f3f3f;
typedef long long LL;
struct edge
{
int en,len,next;
}E[maxn*maxn];
struct node
{
int id,len;
node(int id1=,int len1=){id=id1;len=len1;}
friend bool operator<(const node& x,const node& y){return x.len>y.len;}
};
int head[maxn],num;
int n,m;
int vis[maxn],dis[maxn];
void init(){memset(head,-,sizeof(head));num=;}
void add_edge(int st,int en,int len)
{
E[num].en=en;
E[num].len=len;
E[num].next=head[st];
head[st]=num++;
}
void Dijkstra(int st)
{
for (int i=;i<=n;i++) vis[i]=,dis[i]=INF;
dis[st]=;
priority_queue<node> Q;
Q.push(node(st,));
while (!q.empty())
{
node now=q.top();
Q.pop();
if (vis[now.id]==) continue;
vis[now.id]=;
for (int i=head[now.id];i!=-;i=E[i].next)
{
int en=E[i].en;
int len=E[i].len;
if (!vis[en]&&(dis[en]>dis[now.id]+len))
{
dis[en]=dis[now.id]+len;
Q.push(node(en,dis[en]));
}
}
}
}
int main()
{
init(); return ;
}

Dij-全代码版

 #include<cstring>
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int maxx=,maxn=;
struct Edge
{
int y,to,next;
}e[maxn],e1[maxn];
int head[maxx],tot,head1[maxx],cnt;
int n,m,dis[maxx],S,T,K,vis[maxx];
inline void add(int x,int y,int z){e[++tot]=(Edge){y,z,head[x]};head[x]=tot;}
inline void add1(int x,int y,int z){e1[++cnt]=(Edge){y,z,head1[x]};head1[x]=cnt;}
priority_queue<pair<int,int> >q; //大根堆插入相反数
inline void dijkstra() //处理估价函数
{
memset(dis,0x3f,sizeof dis);
memset(vis,-,sizeof vis);
dis[T]=;
q.push(make_pair(,T));
while (!q.empty())
{
int x=q.top().second;
q.pop();
if (!vis[x])continue;
vis[x]=;
for (int i=head1[x];i;i=e1[i].next)
{
int y=e1[i].y;
if (dis[y]>dis[x]+e1[i].to)
{
dis[y]=dis[x]+e1[i].to;
q.push(make_pair(-dis[y],y));
}
}
}
}
inline void A_star()
{
if (dis[S]==dis[]){puts("-1");return;}
if (S==T) K++;
memset(vis,,sizeof vis);
q.push(make_pair(-dis[S],S));
while (q.size())
{
int x=q.top().second,d=-q.top().first-dis[x];
q.pop();
vis[x]++;
if (vis[T]==K){printf("%d",d);return;}
for (int i=head[x];i;i=e[i].next)
{
int y=e[i].y;
if (vis[y]!=K) q.push(make_pair(-d-e[i].to-dis[y],y));
}
}
puts("-1");
}
int main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
add(x,y,z); add1(y,x,z);
}
cin>>S>>T>>K;
dijkstra();
A_star();
return ;
}

K短路

 template<typename T>
inline void Radix_Sort(T* a,T* b)
{
register const int n=b-a;
size_t size_of_type=sizeof(T);
size_t num_of_buc=size_of_type>>;
unsigned** r=new unsigned *[num_of_buc];
register int i,k;
for(i=; i<num_of_buc;i++)
r[i]=new unsigned [0x10000],memset(r[i],,0x10000*sizeof(unsigned));
register unsigned short tmp_us;
register T *j,*tar;
for (k=;k<num_of_buc;++k)
for (j=a+,tar=a++n;j!=tar;++j)
tmp_us=*(((unsigned short*)j)+k),++r[k][tmp_us];
for (k=;k<num_of_buc;++k)
for (i=;i<=0xffff;++i)
r[k][i]+=r[k][i-];
for (k=;k<num_of_buc;k+=0x2)
{
i=k;
for (j=a+n;j!=a;--j)
tmp_us=*(((unsigned short*)j)+i),b[r[i][tmp_us]--]=*j;
i|=;
if (i==num_of_buc) break;
for (j=b+n;j!=b;--j)
tmp_us=*(((unsigned short*)j)+i),a[r[i][tmp_us]--]=*j;
}
for(int i=;i<num_of_buc;i++) delete[] r[i];
delete [] r;
}

基数排序(位运算优化)

 void us(int a[],const int n)
{
int t[n];
copy(a,a+n,t);
sort(t+,t+n+);
m=unique(t+,t+n+)-t-;
for (int i=;i<=n;i++)
a[i]=lower_bound(t+,t+m+,a[i])-t;
}

离散化

 #include<iostream>
#include<algorithm>
using namespace std;
const int N=;
int a[N],rr[N],ans;
void msort(int l,int r)
{
if (r-l>)
{
int mid=(l+r)>>;
msort(l,mid);
msort(mid,r);
int x=l,y=mid,z=l;
while (x<mid||y<r)
{
if (y>=r||(x<mid&&a[x]<=a[y])) rr[z++]=a[x++];
else rr[z++]=a[y++],ans+=mid-x;
}
for (int i=l;i<r;i++) a[i]=rr[i];
}
}
int main()
{
int n;
cin>>n;
for (int i=;i<n;i++) cin>>a[i];
msort(,n);
cout<<ans;
return ;
}

求逆序对(归并排序)

 void MakeInv(int n,int p)
{
inv[]=;
for(int i=;i<=n;i++)
inv[i]=1ll*(p-p/i)*inv[p%i]%p;
}

线性筛逆元

 #include<iostream>
#include<cstring>
typedef long long ll;
const ll MOD=;
using namespace std;
struct Mat{ll m[][];}a,e;
ll n,p;
Mat Mul(Mat x,Mat y)
{
Mat c;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
c.m[i][j]=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
for(int k=;k<=n;k++)
c.m[i][j]=c.m[i][j]%MOD+x.m[i][k]*y.m[k][j]%MOD;
return c;
}
Mat qpow(Mat x,ll b)
{
Mat ans=e;
while (b)
{
if (b&) ans=Mul(ans,x);
x=Mul(x,x);
b>>=;
}
return ans;
} int main()
{
cin>>n>>p;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
cin>>a.m[i][j];
for(int i=;i<=n;i++)
e.m[i][i]=;
Mat ans=qpow(a,p);
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
cout<<ans.m[i][j]%MOD<<' ';
cout<<'\n';
}
return ;
}

矩阵快速幂

 #include<iostream>
#include<cstdio>
using namespace std;
int n,m,he,ta,T;
int f[],q[],num[];
int main()
{
int w,v,s;
scanf("%d%d",&m,&n);
for (int i=;i<=n;i++)
{
scanf("%d%d%d",&w,&v,&s);
if (s>m/w) s=m/w;
for (int d=;d<w;d++)
{
he=ta=;
for (int j=;j<=(m-d)/w;j++)
{
int tmp=f[j*w+d]-v*j;
while (he<ta&&q[ta-]<=tmp) --ta;
q[ta]=tmp,num[ta++]=j;
while (he<ta&&j-num[he]>s) ++he;
f[j*w+d]=max(f[j*w+d],q[he]+v*j);
}
}
}
printf("%d",f[m]);
return ;
}

单调队列优化多重背包

 //以"滑动窗口"为例
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e6+;
int n,k,a[N],q[N];
int main()
{
scanf("%d%d",&n,&k);
for (int i=;i<=n;++i) scanf("%d",&a[i]);
int front=,rear=;
for (int i=;i<=n;++i)
{
while (front<=rear&&q[front]+k<=i) ++front;
while (front<=rear&&a[i]<a[q[rear]]) --rear;
q[++rear]=i;
if (i>=k) printf("%d ",a[q[front]]);
}
putchar('\n');
memset(q,,sizeof(q)); //q多次利用
front=,rear=;
for (int i=; i<=n;++i)
{
while (front<=rear&&q[front]+k<=i) ++front;
while (front<=rear&&a[i]>a[q[rear]]) --rear;
q[++rear]=i;
if (i>=k) printf("%d ",a[q[front]]);
}
return ;
}

单调队列

 //洛谷P1247
#include<cstdio>
int n,a[];
int main()
{
scanf("%d",&n);
int check=;
for (int i=;i<=n;i++){scanf("%d",&a[i]);check^=a[i];}
if (!check){printf("lose");return ;}
for (int i=;i<=n;i++)
{
if ((check^a[i])<a[i])
{
printf("%d %d\n",a[i]-(check^a[i]),i);
for (int j=;j<=n;j++)
(j!=i)?printf("%d ",a[j]):printf("%d ",check^a[i]);
break;
}
}
return ;
}

Nim游戏输出步骤

OI常用模板的更多相关文章

  1. (长期更新)OI常用模板

    代码很简单的模板就不收录了. DFT 离散傅立叶变换 void dft(pdd *a,int l,bool r){ int i,j=l/2,k; for(i=1;i<l;++i){ if(i&l ...

  2. 【模板】OI常用模板(待补充)

    //PS:最近修改日期:2017-11-07 20:41:44 首先感觉这种模板类的东西写了还是很有意义的,毕竟时不时的可以拿出来借鉴一下. 现在因为刚开始写这一类的东西,所以说还不是很详细,若有读者 ...

  3. OI 常用模板 手写

    线性筛素数 (例题 洛谷P3383) bool p[50000010]; int cnt = 0; int prime[10000010]; inline void init() { int N = ...

  4. NDK(10)Android.mk各属性简介,Android.mk 常用模板

    参考 : http://blog.csdn.net/hudashi/article/details/7059006 本文内容: Android.mk简介, 各属性表, 常用Android.mk模板 1 ...

  5. IDEA学习——模板及其常用模板

    模板及其常用模板 (1)psvm (2)sout sout / soutp / soutv / 变量.sout (3)fori iter增强for循环 itar普通for循环 (4)list.for ...

  6. Vue常用模板语法

    常用模板语法   本篇将在上一篇的基础上记录文本渲染.表达式.过滤器以及常用指令的简单用法. 一.文本渲染 Vue支持动态渲染文本,即在修改属性的同时,实时渲染文本内容.同时为了提高渲染效率,也支持只 ...

  7. html5常用模板下载网站

    html5常用模板下载网站 开创者素材.站长素材.模板之家 推荐葡萄家园素材网,他们网页模板栏目有个HTML模板,很多静态源码.应该是你所需要的. html静态页面模板 还是服饰素材啊 朋友 设计云 ...

  8. NDK(10)Android.mk各属性简介,Android.mk 常用模板--未完

    参考 : http://blog.csdn.net/hudashi/article/details/7059006 1. Android.mk简介 Android.mk文件是GNU Makefile的 ...

  9. WordPress主题模板层次和常用模板函数

    首页: home.php index.php 文章页: single-{post_type}.php – 如果文章类型是videos(即视频),WordPress就会去查找single-videos. ...

随机推荐

  1. JAVA(windows)安装教程

    JAVA(windows)安装教程 一.下载: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133 ...

  2. 设置zabbix (3.4.2)添加监控项,触发器,让CPU使用超过85%就报警:

    zabbix (3.4.2)添加监控项,触发器,让CPU使用超过85%就报警: zabbix自带模板有一个 Template OS Linux模板.这个模板有监控CPU的监控项,如果没有添加一个监控项 ...

  3. 设备树DTS 学习:2-设备树语法

    背景 通过上一讲了解完设备树DTS有关概念,我们这一讲就来基于设备树例程,学习设备树的语法规则. 参考:设备树详解dts.设备树语法详解.设备树使用总结 设备树框架 1个dts文件 + n个dtsi文 ...

  4. ZCGL项目解析——概述

    模块清单 微服务模块:routeservice.eurekaservice.configservice 数据服务模块:fdfsservice.hbaseservice 工具服务模块:common 系统 ...

  5. maven杂碎汇总

        本来是想写一篇关于maven知识点的详细总结的,但需要看一本书或教材,然后再汇总一下,这样做自然是好的,这个在年前争取做完.本文是主要记录在工作和学习遇到关于maven的一些困惑.很乐意看到它 ...

  6. 015、Java中定义变量时不设置内容,使用变量前设置内容

    01.代码如下 package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  7. dataGridView与数据源dataTable同步排序

    private void dataGridView1_Sorted(object sender, EventArgs e)         {             string _sortStr ...

  8. git参考

    https://github.com/NewLifeX  (redis.mq.数据海量查询.分布式任务调度)

  9. pyhton输出表格数据出现省略号?(教你很快解决)

    //2019.07.18 pandas是python提供的非常好用的数据分析模块,但是在使用pandas进行数据分析时,有时候需要查看打印的结果,当dataframe行数或者列数比较多的时候,打印结果 ...

  10. 【LeetCode】反转每对括号间的子串

    [问题]给出一个字符串 s(仅含有小写英文字母和括号). 请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果. 注意,您的结果中 不应 包含任何括号. 示例 : 输入:s = ...