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. Jquery制作插件---内容切换

    //需求:点击左右导航箭头,实现内容的切换 //代码如下 <!DOCTYPE html> <html lang="en"> <head> < ...

  2. linux安装软件的几种方法----linux下编译安装软件的一般步骤

    linux安装软件的几种方法: 一.rpm包安装方式步骤: 1.找到相应的软件包,比如soft.version.rpm,下载到本机某个目录: 2.打开一个终端,su -成root用户: 3.cd so ...

  3. 008.Oracle数据库 , 判断字段内容是否为空

    /*Oracle数据库查询日期在两者之间*/ SELECT PKID, OCCUR_DATE, ATA FROM LM_FAULT WHERE ( ( OCCUR_DATE >= to_date ...

  4. javascript实现ul中列表项随机排列

    方法1 <!DOCTYPE html><html lang="en"><head> <script type="text/jav ...

  5. CPU各个具体的指标含义

    CPU各个具体的指标含义解释如下: ①CPU(监测到的master主机上的CPU使用情况) 从图中看出,一共有五个关于CPU的指标.分别如下: 1. User User表示:CPU一共花了多少比例的时 ...

  6. linux桌面系统 镜像下载

    1.Ubuntu 官方下载地址(不推荐,网速较慢):https://www.ubuntu.com/download 阿里云:http://mirrors.aliyun.com/ubuntu-relea ...

  7. Day 23:JAVA SE复习

    作业 1.多线程下载图片 import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream ...

  8. use matplotlib to draw scatter plot

    There are many pionts in this kind of table. How to do it? We can use scatter() to draw it. Code: im ...

  9. python 输出99乘法表

    for i in range(1,10): for j in range(1,i+1): print("%s*%s=%2s"%(i,j,i*j),end=" " ...

  10. SLAM的评测工具evo

    遇到的问题 今天用orbslam2跑euroc数据集,将结果和真实轨迹用evo测评,发现差别特别大: evo_traj tum data.tum CameraTrajectory.txt --plot ...