字符串类
后缀数组
#include<bits/stdc++.h>
using namespace std;
#define maxn 1000007
void read(int &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') fh=-1,ch=getchar();
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
}
char s[maxn];
int n,m,sa[maxn],x[maxn],y[maxn],ct[maxn];
void SA(){
for(register int i=1;i<=n;i++) ct[x[i]=s[i]]++;
for(register int i=2;i<=m;i++) ct[i]+=ct[i-1];
for(register int i=n;i>=1;i--) sa[ct[x[i]]--]=i;
for(register int k=1;k<=n;k<<=1){
int tot=0;
for(register int i=n-k+1;i<=n;i++) y[++tot]=i;
for(register int i=1;i<=n;i++) if(sa[i]>k) y[++tot]=sa[i]-k;
for(register int i=1;i<=m;i++) ct[i]=0;
for(register int i=1;i<=n;i++) ct[x[i]]++;
for(register int i=1;i<=m;i++) ct[i]+=ct[i-1];
for(register int i=n;i>=1;i--) sa[ct[x[y[i]]]--]=y[i],y[i]=0;
swap(x,y);x[sa[1]]=tot=1;
for(register 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]]=tot;
else x[sa[i]]=++tot;
if(tot==n) break;
m=tot;
}
}
int main(){
ios::sync_with_stdio(0);
cin>>(s+1);n=strlen(s+1);
m=122;SA();
for(register int i=1;i<n;i++) printf("%d ",sa[i]);
printf("%d\n",sa[n]);
return 0;
}
manacher
#include<bits/stdc++.h>
using namespace std;
template <typename Tp>
void read(Tp &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-'){
fh=-1;ch=getchar();
}
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
}
int n,opt[22000003];
char s[22000003];
int rgt,mid,ans;
void Init(){
s[0]='~';s[++n]='|';char c=1;
while(c<'a'||c>'z') c=getchar();
while(c>='a'&&c<='z'){
s[++n]=c,s[++n]='|';
c=getchar();
}
}
int main(){
Init();
for(int i=1;i<=n;i++){
if(i<rgt){
opt[i]=min(opt[(mid<<1)-i],rgt-i);
}
else opt[i]=1;
while(s[i-opt[i]]==s[i+opt[i]]) opt[i]++;
if(opt[i]+i>rgt) rgt=opt[i]+i,mid=i;
ans=max(ans,opt[i]);
}
--ans;
// if(ans==-1) ans++;
printf("%d\n",ans);
return 0;
}
数据结构类
堆
include<bits/stdc++.h>
using namespace std;
define maxn 2000007
int n,opt,x,t[maxn],tot;
void pushup(int k){
int s=k;int p=s>>1;
if(!p) return;
while(p&&t[p]>t[s]){
swap(t[p],t[s]);
s=p;p=s>>1;
}
}
void pushdown(int k){
int s=k;int p=s<<1;
while(p<=tot){
//if(t[s]<t[p]) break;
if(p<tot&&t[p]>t[p+1]) p+=1;
if(t[s]<t[p]) break;
swap(t[s],t[p]);
s=p;p=s<<1;
}
}
int main(){
scanf("%d",&n);
while(n--){
scanf("%d",&opt);
if(opt==1){
scanf("%d",&x);
t[++tot]=x;
pushup(tot);
}
if(opt==2) printf("%d\n",t[1]);
if(opt==3){
t[1]=t[tot--];
pushdown(1);
}
}
}
```
---
ST表
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
int n,q;
int a[maxn];
int opt[maxn][32],x,y;
template <typename Tp>
void read(Tp &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-'){
fh=-1;ch=getchar();
}
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
}
void jup(){
for(register int i=1;i<=21;i++){
for(register int j=1;j+(1<<i)-1<=n;j++){
opt[j][i]=max(opt[j][i-1],opt[j+(1<<(i-1))][i-1]);
}
}
}
int query(){
int k=log2(y-x+1);
return max(opt[x][k],opt[y-(1<<k)+1][k]);
}
int main(){
read(n);read(q);
for(register int i=1;i<=n;i++){
read(a[i]);opt[i][0]=a[i];
}
jup();
while(q--){
read(x);read(y);
printf("%d\n",query());
}
return 0;
}
动态DP
#include<bits/stdc++.h>
using namespace std;
template <typename Tp>
void read(Tp &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
if(ch=='-') ch=getchar(),fh=-1;
else fh=1;
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
x*=fh;
}
const int maxn=100007;
const int maxm=200007;
int n,T;
int a[maxn];
int fa[maxn],dep[maxn],size[maxn];
int son[maxn];
int Head[maxn],to[maxm],Next[maxm];
int tot=1;
void add(int x,int y){
to[++tot]=y,Next[tot]=Head[x],Head[x]=tot;
}
struct Matrix{
int mat[2][2];
Matrix(){
memset(mat,0xcf,sizeof(mat));
}
Matrix operator *(Matrix b){
Matrix c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c.mat[i][j]=max(c.mat[i][j],mat[i][k]+b.mat[k][j]);
return c;
}
};
int f[maxn][2];
Matrix val[maxn];
void dfs1(int x,int f,int dp){
fa[x]=f,size[x]=1,dep[x]=dp;
int mx=-1;
for(int i=Head[x];i;i=Next[i]){
int y=to[i];
if(y==f) continue;
dfs1(y,x,dp+1);size[x]+=size[y];
if(size[y]>mx) mx=size[y],son[x]=y;
}
}
int New[maxn],pre[maxn],ind;
int ed[maxn],top[maxn];
void dfs2(int x,int tp){
New[x]=++ind,pre[ind]=x,top[x]=tp;
ed[tp]=max(ed[tp],ind);
f[x][0]=0,f[x][1]=a[x];
val[x].mat[0][0]=val[x].mat[0][1]=0;
val[x].mat[1][0]=a[x];
if(!son[x]) return;
dfs2(son[x],tp);
f[x][0]+=max(f[son[x]][0],f[son[x]][1]);
f[x][1]+=f[son[x]][0];
for(int i=Head[x];i;i=Next[i]){
int y=to[i];
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
f[x][0]+=max(f[y][0],f[y][1]);
f[x][1]+=f[y][0];
val[x].mat[0][0]+=max(f[y][0],f[y][1]);
val[x].mat[0][1]=val[x].mat[0][0];
val[x].mat[1][0]+=f[y][0];
}
}
#define lfc (x<<1)
#define rgc ((x<<1)|1)
#define mid ((l+r)>>1)
Matrix m[maxn<<2];
void pushup(int x){
m[x]=m[lfc]*m[rgc];
}
void build(int x,int l,int r){
if(l==r){
m[x]=val[pre[l]];
return;
}
build(lfc,l,mid);build(rgc,mid+1,r);
pushup(x);
}
int L,R;
Matrix need;
void change(int x,int l,int r){
if(l==r){
m[x]=need;
return;
}
if(L<=mid) change(lfc,l,mid);
else change(rgc,mid+1,r);
pushup(x);
}
Matrix query(int x,int l,int r,int L,int R){
if(l==L&&r==R) return m[x];
if(R<=mid) return query(lfc,l,mid,L,R);
else if(L>mid) return query(rgc,mid+1,r,L,R);
return query(lfc,l,mid,L,mid)*query(rgc,mid+1,r,mid+1,R);
}
void update(int x,int w){
val[x].mat[1][0]+=w-a[x];
a[x]=w;
Matrix bef,aft;
while(x){
L=New[top[x]],R=ed[top[x]];
bef=query(1,1,n,L,R);
L=New[x],need=val[x];
change(1,1,n);
L=New[top[x]],R=ed[top[x]];
aft=query(1,1,n,L,R);
x=fa[top[x]];
val[x].mat[0][0]+=max(aft.mat[0][0],aft.mat[1][0])-max(bef.mat[0][0],bef.mat[1][0]);
val[x].mat[0][1]=val[x].mat[0][0];
val[x].mat[1][0]+=aft.mat[0][0]-bef.mat[0][0];
}
}
int main(){
read(n);read(T);
for(int i=1;i<=n;i++) read(a[i]);
for(int x,y,i=1;i<n;i++){
read(x);read(y);
add(x,y);add(y,x);
}
dfs1(1,0,1);dfs2(1,1);
build(1,1,n);
for(int x,y,i=1;i<=T;i++){
read(x);read(y);
update(x,y);
L=New[1],R=ed[1];
Matrix ans=query(1,1,n,L,R);
printf("%d\n",max(ans.mat[0][0],ans.mat[1][0]));
}
return 0;
}
图论类
负环
// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
#define maxn 2007
#define maxm 6007
int T;
int n,m;
int Head[maxn],Next[maxm],to[maxm],tot,w[maxm];
void add(int x,int y,int z){
to[++tot]=y,Next[tot]=Head[x],Head[x]=tot,w[tot]=z;
}
template <typename Tp>
void read(Tp &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-'){
fh=-1;ch=getchar();
}
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
}
bitset<maxn>inq;
int dis[maxn];
int cnt[maxn];
bool spfa(int s){
memset(dis,0x3f,sizeof(dis));
queue<int>q;inq[s]=1;
q.push(s);cnt[s]=1;dis[s]=0;
while(!q.empty()){
int x=q.front();inq[x]=0;q.pop();
for(int i=Head[x];i;i=Next[i]){
if(dis[x]+w[i]<dis[to[i]]){
dis[to[i]]=dis[x]+w[i];
cnt[to[i]]++;
if(cnt[to[i]]>n) return 1;
if(inq[to[i]]) continue;
q.push(to[i]);inq[to[i]]=1;
}
}
}
return 0;
}
void Reset(){
inq.reset();memset(cnt,0,sizeof(cnt));tot=0;
memset(Head,0,sizeof(Head));memset(Next,0,sizeof(Next));
}
int main(){
read(T);int xx,yy,zz;
while(T--){
read(n);read(m);
Reset();
for(register int i=1;i<=m;i++){
read(xx);read(yy);read(zz);
if(zz>=0) add(xx,yy,zz),add(yy,xx,zz);
else add(xx,yy,zz);
}
if(spfa(1)){
puts("YE5");
}
else puts("N0");
}
return 0;
}
缩点
#include<bits/stdc++.h>
using namespace std;
#define maxn 10003
#define maxm 100003
int n,m,wy[maxn],wn[maxn],x,y;
int dfn[maxn],low[maxn],st[maxn],top,ind,cnt,id[maxn];
bool ins[maxn];
int vy[maxm],vn[maxm],toty,totn,Headn[maxn],Heady[maxn],Nexty[maxm],Nextn[maxm];
struct node{
int x,y;
bool operator <(node a)const{
return a.x==x?a.y<y:a.x<x;
}
};
set <node> s;
int rd[maxn],tp[maxn],tql,fr=1,opt[maxn];
int ans;
template<typename Tp>
void read(Tp &x){
x=0;char ch=0;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-'){
ch=getchar();fh=-1;
}
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
}
void tarjan(int x){
dfn[x]=low[x]=++ind;st[++top]=x;ins[x]=1;
for(int i=Heady[x];i;i=Nexty[i]){
if(dfn[vy[i]]){
if(ins[vy[i]]){
low[x]=min(low[x],dfn[vy[i]]);
}
}
else{
tarjan(vy[i]);
low[x]=min(low[x],low[vy[i]]);
}
}
if(low[x]==dfn[x]){
++cnt;
while(st[top]!=x){
id[st[top]]=cnt;ins[st[top--]]=0;
}
id[st[top--]]=cnt;ins[x]=0;
}
}
int main(){
read(n);read(m);
for(int i=1;i<=n;i++){
read(wy[i]);
}
for(int i=1;i<=m;i++){
read(x);read(y);
vy[++toty]=y,Nexty[toty]=Heady[x],Heady[x]=toty;
}
for(int i=1;i<=n;i++){
if(!dfn[i]) tarjan(i);
}
for(int i=1;i<=n;i++){
for(int j=Heady[i];j;j=Nexty[j]){
if(id[i]==id[vy[j]]) continue;
// if(s.count((node){id[i],id[vy[j]]})) continue;
// s.insert((node){id[i],id[vy[j]]});
vn[++totn]=id[vy[j]],Nextn[totn]=Headn[id[i]],Headn[id[i]]=totn;
rd[id[vy[j]]]++;
}
wn[id[i]]+=wy[i];
}
for(int i=1;i<=cnt;i++){
if(!rd[i]){
tp[++tql]=i;
}
opt[i]=wn[i];
}
while(fr<=tql){
int k=tp[fr++];
for(int i=Headn[k];i;i=Nextn[i]){
rd[vn[i]]--;
if(!rd[vn[i]]) tp[++tql]=vn[i];
opt[vn[i]]=max(opt[vn[i]],opt[k]+wn[vn[i]]);
}
}
for(register int i=1;i<=cnt;i++){
ans=max(ans,opt[i]);
}
printf("%d\n",ans);
return 0;
}