ACM模板大整理
gcd
void gcd(int x,int y)
{
return !y?x:gcd(y,x%y);
}
exgcd
void ex_gcd(int a,int b,int &x,int &y)
{
if (!b)
{
x=1;
y=0;
return ;
}
ex_gcd(b,a%b,y,x);
y-=x*(a/b);
}
注:线性同余方程ax+by=c有解条件为c是gcd(a,b)的倍数
令d=gcd(a,b) 通解公式为x=x0+b/dt y=y0+a/dt
欧拉函数
//O(n)筛法
void make()
{
phi[1]=1;
int N=maxn;
int k;
for(int i=2;i<N;i++)
{
if(!m[i])
p[pt++]=m[i]=i,phi[i]=i-1;
for(int j=0;j<pt && (k=p[j]*i)<N;j++)
{
m[k]=p[j];
if(m[i]==p[j])
{
phi[k]=phi[i]*p[j];
break;
}
else
phi[k]=phi[i]*(p[j]-1);
f(i*k)=f(i)*f(k)
}
}
}
//O(sqrt(n))求单个数的欧拉值
ll eular(ll n)
{
ll ans = n;
for(int i=2; i*i <= n; ++i)
{
if(n%i == 0)
{
ans = ans/i*(i-1);
while(n%i == 0)
n/=i;
}
}
if(n > 1) ans = ans/n*(n-1);
return ans;
}
筛法
//欧拉筛法
for(int i=2;i<=n;i++)
{
if(!vis[i])
prime[cnt++]=i;
for(int j=0;j<cnt && i*prime[j]<=n; j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0) break;
}
}
//埃拉托斯特尼筛法
for (int i=2;i<=N;i++) is[i]=1;
for (int i=2;i<=N;i++)
if (is[i])
for (int j=i*i;j<=2000;j+=i)
is[j]=0;
中国剩余定理
int CRT(int a[],int m[],int n)
{
int M=1;
int ans=0;
for (int i=1;i<=n;i++)
M*=m[i];
for (int i=1;i<=n;i++)
{
int x,y;
int Mi=M/m[i];
exgcd(Mi,m[i],x,y);
ans=(ans+Mi*x*a[i])%M;
}
if (ans<0) ans+=M;
return ans;
}
欧拉定理&费马小定理
欧拉定理:对于任何两个互质的正整数a和m(m>1),有\(a^{\Phi(m)}\equiv1(mod m)\)
费马小定理:当m是质数时,\(a^{m-1}\equiv1(mod m)\)
扩展欧拉定理:
\(a^{b} = a^{b%\Phi(m)},gcd(a,m) = 1\)
\(a^{b} = a^{b},gcd(a,m)\=1 & b<\Phi(m)\)
\(a^{b} = a^{b%\Phi(m)+\Phi(m)},gcd(a,m)\=1 & b>=\Phi(m)\)
树状数组
void modify(int x,int y)
{
while (x<=n)
{
b[x]+=y;
x+=x&-x;
}
}
int query(int x)
{
int ans=0;
while (x)
{
ans+=b[x];
x-=x&-x;
}
return ans;
}
st表
for (int i=1;i<=18;i++)
for (int j=1;j+(1<<i)-1<=n;j++)
st[j][i]=max(st[j][i-1],st[j+(1<<(i-1))][i-1]);
max(st[l][q],st[r-(1<<q)+1][q])
手写堆
struct Heap{
int hp[N], pos[N], sze;
// hp[i]: corresponding vertex (original graph) of node i (heap)
// pos[i]: corresponding node (heap) of vertex i (original graph)
void move(int &x, int y){
swap(hp[x], hp[y]);
swap(pos[hp[x]], pos[hp[y]]);
x = y;
}
void move_up(int x){
while(x > 1 && dis[hp[x]] < dis[hp[x >> 1]])
move(x, x >> 1);
}
void move_down(int x){
while((x << 1) <= sze){
int min_son = x << 1;
if((x << 1) < sze && dis[hp[x << 1 | 1]] < dis[hp[x << 1]]) min_son = x << 1 | 1;
if(dis[hp[x]] <= dis[hp[min_son]]) break;
move(x, min_son);
}
}
int top(){
return hp[1];
}
void push(int u){
hp[++sze] = u, pos[u] = sze;
move_up(pos[u]);
}
void pop(){
hp[1] = hp[sze--], pos[hp[1]] = 1;
move_down(1);
}
void update(int u){
move_up(pos[u]);
}
} heap;
dij
void dij()
{
int r;
while (heap.sze)
{
r=heap.top();
heap.pop();
for (int i=head[r],v;i;i=edge[i].next)
{
v=edge[i].to;
if (edge[i].w>0 && dis[v]-edge[i].ds>dis[r])
{
dis[v]=dis[r]+edge[i].ds;
heap.update(v);
}
}
}
}
树链剖分
#include<cstdio>
#include<algorithm>
typedef long long ll;
#define N 30010
using namespace std;
int n,x,y,m,a[N],f[N],dfn[N],deep[N],head[N],cnt=1,tp[N],ref[N],t,son[N],size[N];
char s[10];
struct hhh
{
int to,next;
}edge[2*N];
struct node
{
int l,r,data,mx;
}tre[4*N];
int read()
{
int ans=0,fu=1;
char j=getchar();
for (;(j<'0' || j>'9') && j!='-';j=getchar()) ;
if (j=='-') fu=-1,j=getchar();
for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
return ans*fu;
}
void add(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void dfs1(int x,int fa,int dep)
{
f[x]=fa;
deep[x]=dep+1;
int mx=0;
for (int i=head[x],v;i;i=edge[i].next)
{
v=edge[i].to;
if (v!=fa)
{
dfs1(v,x,dep+1);
size[x]+=size[v];
if (size[v]>mx) son[x]=v,mx=size[v];
}
}
size[x]++;
}
void dfs2(int x,int top)
{
dfn[x]=++t;
ref[t]=x;
tp[x]=top;
if (son[x]) dfs2(son[x],top);
for (int i=head[x],v;i;i=edge[i].next)
{
v=edge[i].to;
if (v!=son[x] && v!=f[x])
dfs2(v,v);
}
}
void build(int i,int l,int r)
{
tre[i].l=l;
tre[i].r=r;
if (l==r)
{
tre[i].data=a[ref[l]];
tre[i].mx=a[ref[l]];
return ;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tre[i].data=tre[i*2].data+tre[i*2+1].data;
tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx);
}
void modify(int i,int x,int y)
{
if (tre[i].l==x && tre[i].l==tre[i].r)
{
tre[i].data=y;
tre[i].mx=y;
return ;
}
int mid=(tre[i].l+tre[i].r)>>1;
if (x>mid) modify(i*2+1,x,y);
else modify(i*2,x,y);
tre[i].data=tre[i*2].data+tre[i*2+1].data;
tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx);
}
ll query(int i,int l,int r,int p)
{
if (tre[i].l==l && tre[i].r==r)
if (p) return tre[i].data;
else return tre[i].mx;
int mid=(tre[i].l+tre[i].r)>>1;
if (l>mid) return query(i*2+1,l,r,p);
else if (r<=mid) return query(i*2,l,r,p);
else if (p) return query(i*2,l,mid,p)+query(i*2+1,mid+1,r,p);
else return max(query(i*2,l,mid,p),query(i*2+1,mid+1,r,p));
}
ll pathquery(int u,int v,int p)
{
ll ans=0,tmp=-1000000000;
while (tp[u]!=tp[v])
{
if (deep[tp[u]]<deep[tp[v]]) swap(u,v);
if (p) ans+=query(1,dfn[tp[u]],dfn[u],p);
else tmp=max(tmp,query(1,dfn[tp[u]],dfn[u],p));
u=f[tp[u]];
}
if (deep[u]>deep[v]) swap(u,v);
if (p) return ans+query(1,dfn[u],dfn[v],p);
else return max(tmp,query(1,dfn[u],dfn[v],p));
}
int main()
{
n=read();
for (int i=1;i<n;i++)
{
x=read();
y=read();
add(x,y);
add(y,x);
}
for (int i=1;i<=n;i++) a[i]=read();
dfs1(1,0,0);
dfs2(1,1);
build(1,1,n);
m=read();
while (m--)
{
scanf("%s",s);
x=read();
y=read();
if (s[1]=='M')
printf("%lld\n",pathquery(x,y,0));
else if (s[1]=='S')
printf("%lld\n",pathquery(x,y,1));
else modify(1,dfn[x],y);
}
return 0;
}
SG函数
void get_sg()
{
for (int i=1;i<=n;i++)
{
memset(mex,0,sizeof(mex));
for (int j=0;j+m<=i;j++)
mex[sg[j]^sg[i-j-m]]=1;
for (int j=0;j<=n;j++)
if (!mex[j])
{
sg[i]=j;
break;
}
}
}
void init()
{
m[0]=1;
for (int i=1;i<7;i++) m[i]=m[i-1]*10;
sg[0]=1;
for (int i=1,x;i<1000000;i++)
{
for (int j=0;j<6 && m[j]<=i;j++)
{
x=(i/m[j])%10;
if (!x) mex[sg[i/m[j]/10]]=i;
else for (int k=1;k<=x;k++)
if (k<x || i>=m[j+1]) mex[sg[i-k*m[j]]]=i;
else mex[sg[0]]=i;
}
for (int j=0;j<1000000;j++)
if (mex[j]!=i)
{
sg[i]=j;
break;
}
}
}
费用流
bool bfs()
{
for (int i=s;i<=t;i++)
vis[i]=0,cur[i]=head[i],dis[i]=0x3f3f3f3f;
q.push(s);
dis[s]=0;
vis[s]=1;
while(!q.empty())
{
int r=q.front();
q.pop();
vis[r]=0;
for (int i=head[r],v;i;i=edge[i].next)
{
v=edge[i].to;
if (edge[i].w>0 && dis[r]+edge[i].cost<dis[v])
{
dis[v]=dis[r]+edge[i].cost;
if (!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
return dis[t]!=0x3f3f3f3f;
}
int dfs(int x,int f)
{
if (x==t) return ANS+=f*dis[t],f;
int ha=0,now;
vis[x]=1;
for (int &i=cur[x],v;i;i=edge[i].next)
{
v=edge[i].to;
if (vis[v]) continue;
if (edge[i].w>0 && dis[v]==dis[x]+edge[i].cost)
{
now=dfs(v,min(f-ha,edge[i].w));
if (now)
{
ha+=now;
edge[i].w-=now;
edge[i^1].w+=now;
}
}
if (ha==f) return ha;
}
return ha;
}
Splay
#include<cstdio>
#define N 100010
#define which(x) (ls[f[(x)]]==(x))
using namespace std;
int n,m,ls[N],rs[N],val[N],sze[N],cnt[N],f[N],root,idx;
int read()
{
int ans=0,fu=1;
char j=getchar();
for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
return ans*fu;
}
void updt(int x)
{
sze[x]=sze[ls[x]]+sze[rs[x]]+cnt[x];
}
void Rotate(int u)
{
int v=f[u],w=f[v],b=which(u)?rs[u]:ls[u];
which(u)?(ls[v]=b,rs[u]=v):(rs[v]=b,ls[u]=v);
if (w) which(v)?ls[w]=u:rs[w]=u;
f[u]=w,f[v]=u;
if (b) f[b]=v;
updt(v),updt(u);
}
void Splay(int x,int tar)
{
while (f[x]!=tar)
{
if (f[f[x]]!=tar)
{
if (which(f[x])==which(x)) Rotate(f[x]);
else Rotate(x);
}
Rotate(x);
}
if (!tar) root=x;
}
int find(int x)
{
int u=root,v=0;
while (u && val[u]!=x)
{
v=u;
if (x<val[u]) u=ls[u];
else u=rs[u];
}
return u?u:v;
}
void insert(int x)
{
int u=root,v=0;
while (u && val[u]!=x)
{
v=u;
if (x<val[u]) u=ls[u];
else u=rs[u];
}
if (u && val[u]==x)
return (void)(cnt[u]++,sze[u]++,Splay(u,0));
f[++idx]=v;
sze[idx]=1;
val[idx]=x;
cnt[idx]=1;
if (v) x<val[v]?ls[v]=idx:rs[v]=idx;
Splay(idx,0);
}
int getmn(int x)
{
while (ls[x]) x=ls[x];
return x;
}
int getmx(int x)
{
while (rs[x]) x=rs[x];
return x;
}
void erase(int x)
{
int tmp=find(x);
Splay(tmp,0);
if (cnt[tmp]>1) cnt[tmp]--,sze[tmp]--;
else if (!ls[tmp] || !rs[tmp]) root=ls[tmp]+rs[tmp],f[root]=0;
else
{
f[ls[tmp]]=0;
int u=getmx(ls[tmp]);
Splay(u,0);
rs[u]=rs[tmp];
f[rs[tmp]]=u;
updt(u);
}
}
int getkth(int k)
{
int cur=root;
while (cur)
{
if (sze[ls[cur]]>=k) cur=ls[cur];
else if (sze[ls[cur]]+cnt[cur]>=k) return val[cur];
else k-=sze[ls[cur]]+cnt[cur],cur=rs[cur];
}
return val[cur];
}
int getrank(int x)
{
int cur=find(x);
Splay(cur,0);
return sze[ls[cur]]+1;
}
int getpre(int x)
{
int cur=find(x);
if (val[cur]<x) return val[cur];
Splay(cur,0);
return val[getmx(ls[cur])];
}
int getnxt(int x)
{
int cur=find(x);
if (val[cur]>x) return val[cur];
Splay(cur,0);
return val[getmn(rs[cur])];
}
int main()
{
n=read();
for (int i=1,op,a;i<=n;i++)
{
op=read();
a=read();
if (op==1) insert(a);
if (op==2) erase(a);
if (op==3) printf("%d\n",getrank(a));
if (op==4) printf("%d\n",getkth(a));
if (op==5) printf("%d\n",getpre(a));
if (op==6) printf("%d\n",getnxt(a));
}
return 0;
}
#include<cstdio>
#define N 200010
#define inf 1e9+7
#define which(x) (ls[f[(x)]]==(x))
typedef long long ll;
using namespace std;
int n,m,ls[N],rs[N],id[N],lz[N],f[N],root,idx;
ll sum[N],sze[N],val[N];
char s[10];
int read()
{
int ans=0,fu=1;
char j=getchar();
for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
return ans*fu;
}
void push(int x)
{
if (!lz[x]) return ;
if (ls[x])
{
val[ls[x]]+=lz[x];
lz[ls[x]]+=lz[x];
sum[ls[x]]+=1LL*sze[ls[x]]*lz[x];
}
if (rs[x])
{
val[rs[x]]+=lz[x];
lz[rs[x]]+=lz[x];
sum[rs[x]]+=1LL*sze[rs[x]]*lz[x];
}
lz[x]=0;
}
void updt(int x)
{
sum[x]=sum[ls[x]]+sum[rs[x]]+val[x];
sze[x]=sze[ls[x]]+sze[rs[x]]+1;
}
void Rotate(int u)
{
int v=f[u],w=f[v],b=which(u)?rs[u]:ls[u];
//push(v);push(u);
which(u)?(ls[v]=b,rs[u]=v):(rs[v]=b,ls[u]=v);
if (w) which(v)?ls[w]=u:rs[w]=u;
f[u]=w,f[v]=u;
if (b) f[b]=v;
updt(v),updt(u);
}
int find(int x)
{
int u=root,v=0;
while (u && id[u]!=x)
{
v=u;
if (x<id[u]) u=ls[u];
else u=rs[u];
}
return u?u:v;
}
void Splay(int x,int tar)
{
static int stk[N];
int tp=0;
stk[++tp]=x;
while (f[stk[tp]]) stk[tp+1]=f[stk[tp]],tp++;
while (tp) push(stk[tp--]);
while (f[x]!=tar)
{
if (f[f[x]]!=tar)
{
if (which(f[x])==which(x)) Rotate(f[x]);
else Rotate(x);
}
Rotate(x);
}
if (!tar) root=x;
}
void prt()
{
for (int i=1;i<=idx;i++)
printf("%d: f %d ls %d rs %d sze %lld val %d lz %d id %d sum %lld\n",i,f[i],ls[i],rs[i],sze[i],val[i],lz[i],id[i],sum[i]);
}
void insert(int x,int y)
{
int u=root,v=0;
while (u && id[u]!=x)
{
push(u);
v=u;
if (x<id[u]) u=ls[u];
else u=rs[u];
}
f[++idx]=v;
id[idx]=x;
sum[idx]=y;
sze[idx]=1;
val[idx]=y;
if (v) x<id[v]?ls[v]=idx:rs[v]=idx;
Splay(idx,0);
}
int getmn(int x)
{
while (ls[x]) x=ls[x];
return x;
}
int getmx(int x)
{
while (rs[x]) x=rs[x];
return x;
}
int getpre(int x)
{
int cur=find(x);
if (id[cur]<x) return cur;
Splay(cur,0);
return getmx(ls[cur]);
}
int getnxt(int x)
{
int cur=find(x);
if (id[cur]>x) return cur;
Splay(cur,0);
return getmn(rs[cur]);
}
ll query(int x,int y)
{
int l=getpre(x),r=getnxt(y);
Splay(l,0);Splay(r,l);
return sum[ls[r]];
}
void modify(int x,int y,int z)
{
int l=getpre(x),r=getnxt(y);
//printf("modify find l: %d r: %d\n",l,r);
Splay(l,0);Splay(r,l);
lz[ls[r]]+=z;
val[ls[r]]+=z;
sum[ls[r]]+=1LL*sze[ls[r]]*z;
//prt();
Splay(ls[r],0);
}
void dlt(int x,int y)
{
int l=getpre(x),r=getnxt(y);
Splay(l,0);Splay(r,l);
ls[r]=0;
Splay(r,0);
}
int main()
{
n=read();
insert(-inf,0);
insert(inf,0);
for (int i=1,a,b,c;i<=n;i++)
{
scanf("%s",s+1);
a=read();b=read();
if (s[1]=='I') insert(a,b);
else if (s[1]=='Q') printf("%lld\n",query(a,b));
else if (s[1]=='M')
{
c=read();
modify(a,b,c);
}
else dlt(a,b);
//prt();
}
return 0;
}
完全背包
for(int i=1; i<=n; i++)
for(int j=w[i]; j<=V; j++)//注意此处,与0-1背包不同,这里为顺序,0-1背包为逆序
f[j]=max(f[j],f[j-w[i]]+c[i]);
printf("max=%d\n",f[V]);
匈牙利
bool find(int x)
{
for (int i=head[x];i;i=edge[i].next)
{
if (vis[edge[i].to]) continue;
vis[edge[i].to]=1;
if (!lover[edge[i].to] || find(lover[edge[i].to]))
{
lover[edge[i].to]=x;
return 1;
}
}
return 0;
}
网络流
bool bfs()
{
memset(level,-1,sizeof(level));
level[1]=0;
p.push(1);
while (!p.empty())
{
int r=p.front();
for (int i=head[r];i;i=flow[i].next)
{
int ha=flow[i].to;
if (level[ha]==-1 && flow[i].w>0)
{
level[ha]=level[r]+1;
p.push(ha);
}
}
p.pop();
}
if (level[m]!=-1) return 1;
return 0;
}
int dfs(int now,int f)
{
if (now==m) return f;
for (int i=head[now];i;i=flow[i].next)
{
if (flow[i].w>0 && level[flow[i].to]>level[now])
{
int ha=dfs(flow[i].to,min(flow[i].w,f));
if (ha)
{
flow[i].w-=ha;
flow[i^1].w+=ha;
return ha;
}
}
}
return 0;
}
Tarjan
//有向图
void Tarjan(int x)
{
int v;
dfn[x]=low[x]=++t;
stk.push(x);
instk[x]=1;
for (int i=head[x];i;i=edge[i].next)
{
v=edge[i].to;
if (!dfn[v])
{
Tarjan(v);
low[x]=min(low[v],low[x]);
}
else if (instk[v])
low[x]=min(dfn[v],low[x]);
}
if (dfn[x]==low[x])
{
++num;
do
{
v=stk.top();
stk.pop();
bel[v]=num;
instk[v]=0;
sum[num]++;
}while (v!=x);
}
}
//无向图
void Tarjan(int x)
{
dfn[x]=low[x]=++t;
for (int i=head[x],v;i;i=edge[i].next)
{
v=edge[i].to;
if (i==(from[x]^1)) continue;
if (!dfn[v])
{
from[v]=i;
Tarjan(v);
low[x]=min(low[v],low[x]);
if (low[v]>dfn[x]) is[i]=is[i^1]=1,num++;
}
else low[x]=min(dfn[v],low[x]);
}
}
2-SAT
#include<cstdio>
#include<stack>
#include<cstring>
#include<queue>
#include<vector>
#define N 3005
#define M 500010
using namespace std;
int n,m,cnt=1,head[2*N],color[2*N],op[2*N];
int dfn[2*N],low[2*N],id[2*N],num,tm,in[2*N];
char u,v;
bool wa=1,instk[2*N];
stack <int> stk;
queue <int> q;
vector <int> dag[2*N];
struct hhh
{
int to,next;
}edge[4*M];
inline int _(int x)
{
return x>n?x-n:x+n;
}
void add(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void Tarjan(int x)
{
dfn[x]=low[x]=++tm;
stk.push(x);
instk[x]=1;
for (int i=head[x],r;i;i=edge[i].next)
{
r=edge[i].to;
if (!dfn[r])
{
Tarjan(r);
low[x]=min(low[x],low[r]);
}
else if (instk[r]) low[x]=min(low[x],dfn[r]);
}
int y;
if (dfn[x]==low[x])
{
++num;
do
{
y=stk.top();
stk.pop();
instk[y]=0;
id[y]=num;
}while(y!=x);
}
}
void init()
{
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(id,0,sizeof(id));
memset(color,0,sizeof(color));
memset(op,0,sizeof(op));
memset(head,0,sizeof(head));
memset(in,0,sizeof(in));
for (int i=1;i<=2*n;i++) dag[i].clear();
cnt=1;
wa=1;
tm=num=0;
}
void buildgraph()
{
for (int i=1,a,b;i<=m;i++)
{
scanf("%d%c%d%c",&a,&u,&b,&v);
a++;
b++;
if (u=='h') a+=n;
if (v=='h') b+=n;
add(a,_(b));
add(b,_(a));
}
add(1,1+n);
}
void buildnew()
{
for(int i=1;i<=2*n;i++)
{
for(int j=head[u];j;j=edge[j].next)
{
int v=edge[j].to;
if(id[i]!=id[v]) dag[id[v]].push_back(id[i]),in[id[i]]++;
}
}
}
void topo()
{
for (int i=1;i<=tm;i++) if (in[i]==0) q.push(i);
while (!q.empty())
{
int r=q.front();
q.pop();
int size=dag[r].size();
if(!color[r]) color[r] = 1, color[op[r]] = 2;
for(int i=0;i<size;i++)
{
int v=dag[r][i];
in[v]--;
if(in[v]==0) q.push(v);
}
}
}
int main()
{
while (~scanf("%d%d",&n,&m) && (n && m))
{
init();
buildgraph();
for (int i=1;i<=2*n;i++) if (!dfn[i]) Tarjan(i);
for (int i=1;i<=n;i++)
if (id[i]==id[i+n]) wa=0;
else op[id[i]]=id[i+n],op[id[i+n]]=id[i];
if (!wa)
{
printf("bad luck\n");
continue;
}
buildnew();
topo();
for (int i=2;i<=n;i++)
{
if (color[id[i]]==color[id[1]]) printf("%dw ",i-1);
else printf("%dh ",i-1);
}
printf("\n");
}
return 0;
}
kmp
for (int i=2,j=0;i<=lb;i++)
{
while (j && b[j+1]!=b[i]) j=next[j];
if (b[j+1]==b[i]) j++;
next[i]=j;
}
for (int i=1,j=0;i<=la;i++)
{
while (j && b[j+1]!=a[i]) j=next[j];
if (b[j+1]==a[i]) j++;
if (j==lb) j=next[j],printf("%d\n",i-lb+1);
}
manacher
scanf("%s",s+1);
s[0]='@';
l=strlen(s+1);
cnt++;
for (int i=l;i>=1;i--) s[i*2]=s[i];
for (int i=1;i<=2*l+1;i+=2) s[i]='#';
s[2*l+2]='?';
l=2*l+1;
for (int i=1;i<=l;i++)
printf("%c ",s[i]);
putchar('\n');
mx=mxr=0;
for (int i=1,x;i<=l;i++)
{
if (mxr>i) x=min(a[2*p-i],mxr-i);
else x=1;
while (s[i-x]==s[i+x]) x++;
if (i+x>mxr) mxr=i+x,p=i;
a[i]=x;
printf("%d ",a[i]);
}
spfa
void spfa(int x)
{
q.push(x);
dis[x]=0;
vis[x]=1;
while (!q.empty())
{
int r=q.front();
q.pop();
vis[r]=0;
for (int i=head[r],v;i;i=edge[i].next)
{
v=edge[i].to;
if (dis[v]-edge[i].w<dis[r])
{
dis[v]=edge[i].w+dis[r];
if (!vis[v]) q.push(v),vis[v]=1;
}
}
}
}
最小生成树
void _put(int x)
{
for(int i=head[x];i;i=e[i].next)
if(!vis[e[i].to]) q.push(e[i]);
}
int prime()
{
int Cnt=1,ret=0;
vis[1]=true;
_put(1);
while(Cnt<n)
{
while(1)
{
edge a=q.top();
if(!vis[a.to])
{
vis[a.to]=1;
Cnt++;
ret+=a.w;
_put(a.to);
break;
}
q.pop();
}
}
return ret;
}
for (int i=1;i<=m;i++)
{
if (cnt==n-k) break;
int xx=findfa(edge[i].u),yy=findfa(edge[i].v);
if (xx!=yy)
{
f[xx]=yy;
ans+=edge[i].w;
cnt++;
}
}
01背包
for (int i=1;i<=n;i++)
for (int j=v;j>=a[i];j--)
dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
后缀数组
void suffix_sort()
{
int *x=buf1,*y=buf2,m=300;
for (int i=0;i<=m;i++) buc[i]=0;
for (int i=1;i<=n;i++) buc[x[i]=s[i]]++;
for (int i=1;i<=m;i++) buc[i]+=buc[i-1];
for (int i=n;i;i--) sa[buc[x[i]]--]=i;
for (int k=1;k<=n;k<<=1)
{
int p=0;
for (int i=n-k+1;i<=n;i++)
y[++p]=i;
for (int i=1;i<=n;i++)
if (sa[i]>k) y[++p]=sa[i]-k;
for (int i=0;i<=m;i++) buc[i]=0;
for (int i=1;i<=n;i++) buc[x[y[i]]]++;
for (int i=1;i<=m;i++) buc[i]+=buc[i-1];
for (int i=n;i;i--) sa[buc[x[y[i]]]--]=y[i];
swap(x,y),x[sa[1]]=p=1;
for (int i=2;i<=n;i++)
if (y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])
x[sa[i]]=p;
else x[sa[i]]=++p;
if ((m=p)>=n) break;
}
for (int i=1;i<=n;i++) rnk[sa[i]]=i;
for (int i=1,j,k=0;i<=n;i++)
{
if (rnk[i]==1) continue;
if (k) k--;
j=sa[rnk[i]-1];
while (s[i+k]==s[j+k] && i+k<=n && j+k<=n) k++;
height[rnk[i]]=k;
}
}