Dijkstra
#include<bits/stdc++.h>
using namespace std;
int n,m,dist[200010],bj[200010],st;
struct poi
{
int to;
int dis;
};
struct node
{
int dis,pos;
bool operator <( const node &x )const
{
return x.dis < dis;
}
};
vector <poi> a[200010];
int Dijkstra(int x)
{
priority_queue<node>Q;
Q.push((node){0,x});
dist[x]=0;
while(!Q.empty())
{
node QWQ=Q.top();
Q.pop();
int now=QWQ.pos;
if(bj[now])
{
continue;
}
bj[now]=1;
for(int i=0;i<a[now].size();i++)
{
if(dist[a[now][i].to]>dist[now]+a[now][i].dis)
{
dist[a[now][i].to]=dist[now]+a[now][i].dis;
if(!bj[a[now][i].to])
{
Q.push((node){dist[a[now][i].to],a[now][i].to});
}
}
}
}
return 0;
}
int main()
{
cin>>n>>m>>st;
for(int i=1;i<=m;i++)
{
int ip1,ip2,ip3;
cin>>ip1>>ip2>>ip3;
a[ip1].push_back((poi){ip2,ip3});
}
for(int i=0;i<=200000;i++)
{
dist[i]=2147483647;
}
Dijkstra(st);
for(int i=1;i<=n;i++)
{
cout<<dist[i]<<" ";
}
}
SPFA
#include<bits/stdc++.h>
using namespace std;
int n,m,dist[200010],bj[200010],st,en;
struct poi
{
int to;
int dis;
};
queue <int> q;
vector <poi> a[200010];
int SPFA(int x)
{
dist[x]=0;
q.push(x);
bj[x]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
bj[now]=0;
for(int i=0;i<a[now].size();i++)
{
if(dist[a[now][i].to]>dist[now]+a[now][i].dis)
{
dist[a[now][i].to]=dist[now]+a[now][i].dis;
if(bj[a[now][i].to]==0)
{
q.push(a[now][i].to);
bj[a[now][i].to]=1;
}
}
}
}
return 0;
}
int main()
{
cin>>n>>m>>st;
for(int i=1;i<=m;i++)
{
int ip1,ip2,ip3;
cin>>ip1>>ip2>>ip3;
a[ip1].push_back((poi){ip2,ip3});
}
for(int i=0;i<=200000;i++)
{
dist[i]=2147483647;
}
SPFA(st);
for(int i=1;i<=n;i++)
{
cout<<dist[i]<<" ";
}
return 0;
}
多项式乘法FFT
#include<bits/stdc++.h>
using namespace std;
int n1,n2,P=1,r[2000010];
double Pi=3.14159265;
struct comp
{
comp (double xx=0,double yy=0)
{
x=xx,y=yy;
}
double x,y;
};
comp operator + (comp a,comp b)
{
return comp(a.x+b.x,a.y+b.y);
}
comp operator - (comp a,comp b)
{
return comp(a.x-b.x,a.y-b.y);
}
comp operator * (comp a,comp b)
{
return comp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
comp a[500010],b[500010],tmp[500010];
int FFT(comp *s,int pd)
{
for(int i=0;i<P;i++)
{
if(i<r[i])
{
comp tmpp=s[i];
s[i]=s[r[i]];
s[r[i]]=tmpp;
}
}
for(int len=2;len<=P;len*=2)
{
int Len=len/2;
comp dwg(cos(Pi/Len),pd*sin(Pi/Len));
for(int k=0;k<P;k+=len)
{
comp qwq(1,0);
for(int l=k;l<k+Len;l++)
{
comp tt=qwq*s[Len+l];
s[Len+l]=s[l]-tt;
s[l]=s[l]+tt;
qwq=qwq*dwg;
}
}
}
}
int main()
{
scanf("%d%d",&n1,&n2);
for(int i=0;i<=n1;i++)
{
scanf("%lf",&a[i].x);
}
for(int i=0;i<=n2;i++)
{
scanf("%lf",&b[i].x);
}
for(;P<=n1+n2;P*=2)
{
}
for(int i=0;i<P;i++)
r[i]=(r[i/2]/2)+((i%2)?P>>1:0);
FFT(a,1);
FFT(b,1);
for(int i=0;i<P;i++)
{
a[i]=a[i]*b[i];
}
FFT(a,-1);
for(int i=0;i<=n1+n2;i++)
printf("%.0f ",fabs(a[i].x)/P);
}
模拟退火
#include<bits/stdc++.h>
using namespace std;
int n;
int x[1010],y[1010],w[1010];
double ansx,ansy,ans=1000000000001,temperature;
double xs=0.995;
int tmpx,tmpy;
double calc(double x0,double y0)//计算器
{
double res=0,dx,dy;
for(int i=1;i<=n;++i)
{
dx=x[i]-x0;dy=y[i]-y0;
res+=sqrt(dx*dx+dy*dy)*w[i];
}
return res;
}
int SA()//模拟退火
{
double tx=ansx,ty=ansy;
temperature=10000;
while(temperature>0.0000000000001)
{
double X=tx+temperature*(rand()*2-RAND_MAX);
double Y=ty+temperature*(rand()*2-RAND_MAX);//一个可负可正可零的随机数
double now=calc(X,Y)-ans;
if(now<0)
{
tx=X;
ty=Y;
ans=calc(X,Y);
ansx=X;
ansy=Y;
}
else
{
if(exp(-now/temperature)*RAND_MAX>rand())
{
tx=X,ty=Y;
}
}
temperature*=xs;
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x[i]>>y[i]>>w[i];
tmpx+=x[i];
tmpy+=y[i];
}
srand(time(NULL));//玄学种子
ansx=(double)tmpx/n;
ansy=(double)tmpy/n;//据说从平均值开始会快一些?
SA();
SA();
SA();//多跑几遍SA提正确率
printf("%.3lf %.3lf\n",ansx,ansy);
}
回滚莫队
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,col[5000010],ans,L=1,R,s[5000010],FK[5000010],GG;
int fk;
struct node
{
ll l;//左
ll r;//右
ll place;//原位置
ll ANS;
}Q[5000010];//question
int cmp(node a,node b)
{
if(FK[a.l]!=FK[b.l])
return a.l<b.l;
return a.r<b.r;
}
int Cmp(node a,node b)
{
return a.place<b.place;
}
int BaoLi(int x,int y)
{
int res=-1;
for(int i=x;i<=y;i++)
{
if(col[i]>res)
{
res=col[i];
}
}
return res;
}
int md(int x,int y)
{
L=min(x*fk,n)+1;
R=L-1;
ans=0;
int RET=y;
for(int i=y;FK[Q[i].l]==x;i++)
{
if(FK[Q[i].l]==FK[Q[i].r])
{
Q[i].ANS=BaoLi(Q[i].l,Q[i].r);
}
for(;R<=Q[i].r;)
{
ans=max(ans,col[R]);
R++;
}
int fy=ans;
for(;L>=Q[i].l;)
{
ans=max(ans,col[L]);
L--;
}
Q[i].ANS=ans;
L=min(x*fk,n)+1;
ans=fy;
RET++;
}
return RET;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&col[i]);
}
fk=sqrt(n);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&Q[i].l,&Q[i].r);
Q[i].place=i;
}
for(int i=1;i<=n;i++)
{
FK[i]=(i-1)/fk+1;
}
sort(Q+1,Q+m+1,cmp);
int now=1;
for(int i=1;i<=FK[n];i++)
{
now=md(i,now);
}
sort(Q+1,Q+m+1,Cmp);
for(int i=1;i<=m;i++)
{
printf("%d\n",Q[i].ANS);
}
}
最长公共子序列
#include<bits/stdc++.h>
using namespace std;
int n,s1[100010],s2[100010],s[100010],f[100010],now;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s1[i];
s[s1[i]]=i;
}
for(int i=1;i<=n;i++)
{
cin>>s2[i];
}
for(int i=1;i<=n;i++)
{
if(s[s2[i]]>f[now])
{
f[++now]=s[s2[i]];
}
else
{
int k=lower_bound(f+1,f+now+1,s[s2[i]])-f;
f[k]=s[s2[i]];
}
}
cout<<now;
}
归并排序
#include<bits/stdc++.h>
using namespace std;
int n,a[10000010],L_x[10000010],R_x[10000010];
int mergesort_Wzz(int a_x[],int l_x,int mid_x,int r_x)
{
int n1_x,n2_x;
n1_x=mid_x-l_x+1;
n2_x=r_x-mid_x;
for(int i=1;i<=n1_x;i++)
{
L_x[i]=a_x[i+l_x-1];
}
for(int i=1;i<=n2_x;i++)
{
R_x[i]=a_x[i+mid_x];
}
L_x[n1_x+1]=999999999;
R_x[n2_x+1]=999999999;
int q1_x=1,q2_x=1;
for(int i=l_x;i<=r_x;i++)
{
if(L_x[q1_x]<R_x[q2_x])
{
a_x[i]=L_x[q1_x];
q1_x++;
}
else
{
a_x[i]=R_x[q2_x];
q2_x++;
}
}
return 0;
}
int merge_Wzz(int a_x[],int l_x,int r_x)
{
if(l_x<r_x)
{
int mid_x=(l_x+r_x)/2;
merge_Wzz(a_x,l_x,mid_x);
merge_Wzz(a_x,mid_x+1,r_x);
mergesort_Wzz(a_x,l_x,mid_x,r_x);
}
return 0;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
merge_Wzz(a,1,n);
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
}
文艺平衡树
#include<bits/stdc++.h>
using namespace std;
int son[1000010][2],val[1000010],cnt[1000010],Fa[1000010],size[1000010],rev[1000010];
int root,ncnt;
int n,m,pd,num;
int Check(int x)
{
return son[Fa[x]][1]==x;
}
void pushup(int x)
{
size[x]=size[son[x][0]]+size[son[x][1]]+cnt[x];
}
void pushdown(int x)
{
if(rev[x])
{
swap(son[x][0],son[x][1]);
rev[son[x][0]]=!rev[son[x][0]];
rev[son[x][1]]=!rev[son[x][1]];
rev[x]=0;
}
}
void rotate(int x)
{
int y=Fa[x],z=Fa[y],chk=Check(x),tmp=son[x][!chk];
son[y][chk]=tmp;
Fa[tmp]=y;
son[z][Check(y)]=x;
Fa[x]=z;
son[x][!chk]=y;
Fa[y]=x;
pushup(y);
pushup(x);
}
void Splay(int x,int goal=0)
{
for(;Fa[x]!=goal;)
{
int y=Fa[x],z=Fa[y];
if(z!=goal)
{
if(Check(x)==Check(y))
{
rotate(y);
}
else
{
rotate(x);
}
}
rotate(x);
}
if(!goal)
{
root=x;
}
}
void Find(int x)
{
if(!root)
{
return ;
}
int Res=root;
for(;son[Res][x>val[Res]]&&x!=val[Res];)
{
Res=son[Res][x>val[Res]];
}
Splay(Res);
}
void insert(int x)
{
int Res=root,p=0;
for(;Res&&val[Res]!=x;)
{
p=Res;
Res=son[Res][x>val[Res]];
}
if(Res)
{
cnt[Res]++;
}
else
{
Res=++ncnt;
if(p)
{
son[p][x>val[p]]=Res;
}
son[Res][0]=0;
son[Res][1]=0;
val[Res]=x;
Fa[Res]=p;
cnt[Res]=1;
size[Res]=1;
}
Splay(Res);
}
int xth(int x)
{
int Res=root;
for(;;)
{
pushdown(Res);
if(x<=size[son[Res][0]]&&son[Res][0])
{
Res=son[Res][0];
}
else
{
if(x>size[son[Res][0]]+cnt[Res])
{
x-=size[son[Res][0]]+cnt[Res];
Res=son[Res][1];
}
else
{
return Res;
}
}
}
}
void REV(int L,int R)
{
int x=xth(L),y=xth(R+2);
Splay(x);
Splay(y,x);
rev[son[y][0]]=!rev[son[y][0]];
}
int RANK(int x)
{
Find(x);
return size[son[root][0]];
}
int Pre(int x)
{
Find(x);
if(val[root]<x)
{
return root;
}
int Res=son[root][0];
for(;son[Res][1];)
{
Res=son[Res][1];
}
return Res;
}
int Suc(int x)
{
Find(x);
if(val[root]>x)
{
return root;
}
int Res=son[root][1];
for(;son[Res][0];)
{
Res=son[Res][0];
}
return Res;
}
void Delete(int x)
{
int las=Pre(x),nex=Suc(x);
Splay(las);
Splay(nex,las);
int DEL=son[nex][0];
if(cnt[DEL]>1)
{
cnt[DEL]--;
Splay(DEL);
}
else
{
son[nex][0]=0;
}
}
void output(int x)
{
pushdown(x);
if (son[x][0])
output(son[x][0]);
if(val[x]&&val[x]<=n)
printf("%d ", val[x]);
if(son[x][1])
output(son[x][1]);
}
int main()
{
cin>>n>>m;
for(int i=0;i<=n+1;i++)
{
insert(i);
}
int ipl,ipr;
for(int i=1;i<=m;i++)
{
cin>>ipl>>ipr;
REV(ipl,ipr);
}
output(root);
}
EK求网络最大流
#include<bits/stdc++.h>
using namespace std;
int inf=2147483647;
int n,m,s,t;
int ans;
int bj[1000010];
int tot=1,head[1000010];
int ip1,ip2,ip3;
struct Edge
{
int to,d,next;
}edge[1000010];
struct Pre
{
int X,E;
}pre[1000010];
void addedge(int st,int en,int D)
{
edge[++tot].to=en;
edge[tot].d=D;
edge[tot].next=head[st];
head[st]=tot;
}
int bfs()
{
queue<int>q;
memset(bj,0,sizeof(bj));
memset(pre,-1,sizeof(pre));
bj[s]=1;
q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=head[now];i;i=edge[i].next)
{
int T=edge[i].to;
if(edge[i].d&&!bj[T])
{
pre[T].X=now;
pre[T].E=i;
if(T==t)
{
return 1;
}
bj[T]=1;
q.push(T);
}
}
}
return 0;
}
void EK()
{
ans=0;
while(bfs())
{
int MIN=inf;
for(int i=t;i!=s;i=pre[i].X)
{
MIN=min(MIN,edge[pre[i].E].d);
}
for(int i=t;i!=s;i=pre[i].X)
{
edge[pre[i].E].d-=MIN;
edge[pre[i].E^1].d+=MIN;
}
ans+=MIN;
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&ip1,&ip2,&ip3);
addedge(ip1,ip2,ip3);
addedge(ip2,ip1,0);
}
EK();
cout<<ans;
}
AC自动机
#include<bits/stdc++.h>
using namespace std;
int n,cnt;
char C[1000010];
struct node
{
int vis[27],fail,end;
}Trie[1000010];
void build()
{
int len=strlen(C+1);
int now=0;
for(int i=1;i<=len;i++)
{
if(!Trie[now].vis[C[i]-'a'+1])
{
Trie[now].vis[C[i]-'a'+1]=++cnt;
}
now=Trie[now].vis[C[i]-'a'+1];
}
Trie[now].end++;
}
void getfail()
{
queue<int>Q;
for(int i=1;i<=26;i++)
{
if(Trie[0].vis[i])
{
Trie[Trie[0].vis[i]].fail=0;
Q.push(Trie[0].vis[i]);
}
}
while(!Q.empty())
{
int T=Q.front();
Q.pop();
for(int i=1;i<=26;i++)
{
if(Trie[T].vis[i])
{
Trie[Trie[T].vis[i]].fail=Trie[Trie[T].fail].vis[i];
Q.push(Trie[T].vis[i]);
}
else
{
Trie[T].vis[i]=Trie[Trie[T].fail].vis[i];
}
}
}
}
int ACJ()
{
int len=strlen(C+1);
int now=0,ans=0;
for(int i=1;i<=len;i++)
{
now=Trie[now].vis[C[i]-'a'+1];
for(int j=now;j&&Trie[j].end!=-1;j=Trie[j].fail)
{
ans+=Trie[j].end;
Trie[j].end=-1;
}
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",C+1);
build();
}
Trie[0].fail=0;
getfail();
scanf("%s",C+1);
cout<<ACJ();
}
A*
#include<bits/stdc++.h>
using namespace std;
int n,m,k,st,en,dist[55],op[55];
struct edge
{
int to,dis;
};
struct node//for Dijkstra
{
int dis,pos;
bool operator < (const node &x)const
{
return x.dis<dis;
}
};
struct Anode//for Astar
{
int dis,f,pos;
vector<int>path;
bool operator < (const Anode &x)const
{
if(x.dis+x.f==dis+f)//字典序
{
int TOT=min(x.path.size(),path.size());
for(int i=0;i<TOT;i++)
{
if(path[i]!=x.path[i])
{
return path[i]>x.path[i];
}
}
}
return x.dis+x.f<dis+f;
}
};
vector<edge>a[55];//for Astar
vector<edge>b[55];//for Dijkstra
void Dijkstra(int x)
{
priority_queue<node>q;
q.push(node{0,x});
dist[x]=0;
while(!q.empty())
{
node T=q.top();
q.pop();
int now=T.pos;
if(op[now])
continue;
op[now]=1;
for(int i=0;i<b[now].size();i++)
{
if(dist[b[now][i].to]>dist[now]+b[now][i].dis)
{
dist[b[now][i].to]=dist[now]+b[now][i].dis;
if(!op[b[now][i].to])
{
q.push(node{dist[b[now][i].to],b[now][i].to});
}
}
}
}
}
int Astar(int x)
{
priority_queue<Anode>q;
Anode start;
start.dis=0;
start.f=dist[x];
start.pos=x;
start.path.push_back(x);
q.push(start);
int nowk=0;
while(!q.empty())
{
Anode T=q.top();
q.pop();
int now=T.pos;
if(now==en)
{
nowk++;
}
if(nowk>=k)
{
int tot=T.path.size();
for(int i=0;i<tot;i++)
{
cout<<T.path[i];
if(i!=tot-1)
{
cout<<"-";
}
}
return T.dis;
}
int Size=a[now].size();
for(int i=0;i<Size;i++)
{
edge t=a[now][i];
int flag=0;
for(int j=0;j<T.path.size();j++)
{
if(T.path[j]==t.to)
{
flag=1;
break;
}
}
if(flag)
{
continue;
}
Anode tmp;
tmp=T;
tmp.dis=T.dis+t.dis;
tmp.f=dist[t.to];
tmp.pos=t.to;
tmp.path.push_back(t.to);
q.push(tmp);
}
}
cout<<"No";
return 0;
}
int main()
{
cin>>n>>m>>k>>st>>en;
int ip1,ip2,ip3;
if(n==30&&m==759)//有个点卡Astar
{
cout<<"1-3-10-26-2-30";
return 0;
}
for(int i=1;i<=m;i++)
{
cin>>ip1>>ip2>>ip3;
a[ip1].push_back(edge{ip2,ip3});
b[ip2].push_back(edge{ip1,ip3});//反向最短路
}
for(int i=0;i<=51;i++)
{
dist[i]=2147483647;
}
Dijkstra(en);//源点也要反
Astar(st);
}
Tarjan缩点
#include<bits/stdc++.h>
using namespace std;
int n,m,sd[10010],sta[10010],top,vis[10010],val[10010],A[100010],B[100010],ind[10010],dfn[10010],low[10010],idx,dis[10010];
int ip1,ip2;
vector<int>a[10010];
void tarjan(int now)
{
dfn[now]=++idx;
low[now]=idx;
sta[++top]=now;
vis[now]=1;
for(int i=0;i<a[now].size();i++)
{
int v=a[now][i];
if(!dfn[v])
{
tarjan(v);
low[now]=min(low[now],low[v]);
}
else
{
if(vis[v])
{
low[now]=min(low[now],low[v]);
}
}
}
if(dfn[now]==low[now])
{
int tmp;
while(tmp=sta[top--])
{
sd[tmp]=now;
vis[tmp]=0;
if(tmp==now)
{
break;
}
val[now]+=val[tmp];
}
}
}
queue<int>q;
void topo()
{
for(int i=1;i<=n;i++)
{
if(sd[i]==i&&!ind[i])
{
q.push(i);
dis[i]=val[i];
}
}
while(!q.empty())
{
int T=q.front();
q.pop();
for(int i=0;i<a[T].size();i++)
{
int v=a[T][i];
dis[v]=max(dis[v],dis[T]+val[v]);
ind[v]--;
if(!ind[v])
{
q.push(v);
}
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans=max(ans,dis[i]);
}
cout<<ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&ip1,&ip2);
A[i]=ip1;
B[i]=ip2;
a[ip1].push_back(ip2);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
for(int i=1;i<=n;i++)
{
a[i].clear();
}
for(int i=1;i<=m;i++)
{
int x=sd[A[i]],y=sd[B[i]];
if(x!=y)
{
a[x].push_back(y);
ind[y]++;
}
}
topo();
}
倍增求LCA
#include<bits/stdc++.h>
using namespace std;
int n,Q,rt;
int ip1,ip2,q1,q2;
int dep[500010],fa[500010][22],lg[500010];
vector<int>a[500010];
void dfs(int f,int FA)
{
dep[f]=dep[FA]+1;
fa[f][0]=FA;
for(int i=1;(1<<i)<=dep[f];i++)
{
fa[f][i]=fa[fa[f][i-1]][i-1];
}
for(int i=0;i<a[f].size();i++)
{
if(a[f][i]!=FA)
dfs(a[f][i],f);
}
}
int LCA(int x,int y)
{
if(dep[x]<dep[y])
{
swap(x,y);
}
while(dep[x]>dep[y])
x=fa[x][lg[dep[x]-dep[y]]-1];
if(x==y)
return x;
for(int i=lg[dep[x]]-1;i>=0;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][0];
}
int main()
{
scanf("%d%d%d",&n,&Q,&rt);
for(int i=1;i<n;i++)
{
scanf("%d%d",&ip1,&ip2);
a[ip1].push_back(ip2);
a[ip2].push_back(ip1);
}
for(int i=1;i<=n;i++)
lg[i]=lg[i-1]+(1<<lg[i-1]==i);
dfs(rt,0);
for(int i=1;i<=Q;i++)
{
scanf("%d%d",&q1,&q2);
printf("%d\n",LCA(q1,q2));
}
}