板子合集
my 缺省源
点击查看代码
#include
#include
#include
#include
#include
#include
#include
数论
极速行列式
模数为质数
点击查看代码
inline int det(int n){
int res=1;bool flag=0;
for(int j=1;j<=n;++j){
if(!a[j][j]){
for(int i=j+1;i<=n;++i)
if(a[i][j]){std::swap(a[i],a[j]);flag^=1;break;}
}
if(!a[j][j]) return 0;
res=(ll)res*a[j][j]%mod;
int tmp=qpow(a[j][j],mod-2);
for(int k=j;k<=n;++k) a[j][k]=(ll)a[j][k]*tmp%mod;
for(int i=j+1;i<=n;++i){
tmp=mod-a[i][j];
for(int k=j;k<=n;++k) modadd(a[i][k],(ll)tmp*a[j][k]%mod);
}
}
return flag?mod-res:res;
}
模数不为质数
点击查看代码
inline int det(int a[N][N],int n){
int res=1;bool flag=0;
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j)
while(a[j][i]){
int tmp=a[i][i]/a[j][i];
for(int k=i;k<=n;++k) moddel(a[i][k],(ll)tmp*a[j][k]%mod);
std::swap(a[i],a[j]);flag^=1;
}
for(int i=1;i<=n;++i) res=(ll)res*a[i][i]%mod;
if(!res) return 0;
return flag?mod-res:res;
}
my poly
点击查看代码
namespace poly{
const int G=3,Gi=qpow(G,mod-2);
inline void poly_det(int n,int *a,int *b){for(int i=1;i>1]>>1)|((i&1)<<(l-1));
for(int i=0;i>1]>>1)|((i&1)?l:0);
for(int i=0;i
字符串
manacher
点击查看代码
int manacher(){
rint mx=0,id=0,ans=0;
for(rint i=1;i<=n;++i){
if(imx) mx=i+l[i],id=i;
ans=max(ans,l[i]);
}
return ans-1;
}
KMP
点击查看代码
#include
#include
#include
using namespace std;
const int N=1e6+13;
char s[N],t[N];
int n,m,nxt[N];
inline void init(){
nxt[1]=0;
for(int i=2,j=0;i<=n;++i){
while(j&&t[j+1]!=t[i]) j=nxt[j];
if(t[j+1]==t[i]) ++j;
nxt[i]=j;
}
}
inline void KMP(){
for(int i=1,j=0;i<=m;++i){
while(j&&t[j+1]!=s[i]) j=nxt[j];
if(t[j+1]==s[i]) ++j;
if(j==n) printf("%d\n",i-n+1),j=nxt[j];
}
}
int main(){
scanf("%s",s+1);m=strlen(s+1);
scanf("%s",t+1);n=strlen(t+1);
init();
KMP();
for(int i=1;i<=n;++i) printf("%d ",nxt[i]);
return 0;
}
ACAM
点击查看代码
struct Aho_Corasick_Automaton{
#define ACA Aho_Corasick_Automaton
int ch[N][30],fail[N],val[N],cnt;
ACA(){cnt=0;}
inline void ins(char *s){
int len=strlen(s),now=0;
for(int i=0;iq;fail[0]=0;
for(int c=0;c<26;++c){
int u=ch[0][c];
if(u) fail[ch[0][c]]=0,q.push(ch[0][c]);
}
while(!q.empty()){
int u=q.front();q.pop();
for(int c=0;c<26;++c){
if(ch[u][c]) fail[ch[u][c]]=ch[fail[u]][c],q.push(ch[u][c]);
else ch[u][c]=ch[fail[u]][c];
}
}
}
inline int query(char *s){
int n=strlen(s),now=0,res=0;
for(int i=0;i
exKMP
点击查看代码
#include
#include
#include
using namespace std;
const int N=2e7+13;
char s[N],t[N];
int n,m,nxt[N],ext[N];
inline void init(){
nxt[1]=n;
for(int i=2,l=0,r=0;i<=n;++i){
int tmp=nxt[i-l+1];
if(i<=r){
if(i+tmp<=r) nxt[i]=tmp;
else nxt[i]=r-i+1;
}
while(i+nxt[i]<=n&&t[i+nxt[i]]==t[1+nxt[i]]) ++nxt[i];
if(i+nxt[i]-1>r) r=i+nxt[i]-1,l=i;
}
}
inline void exKMP(){
for(int i=1,l=0,r=0;i<=m;++i){
int tmp=nxt[i-l+1];
if(i<=r){
if(i+tmp<=r) ext[i]=tmp;
else ext[i]=r-i+1;
}
while(i+ext[i]<=m&&1+ext[i]<=n&&s[i+ext[i]]==t[1+ext[i]]) ++ext[i];
if(i+ext[i]-1>r) r=i+ext[i]-1,l=i;
}
}
inline void file(){
freopen("P5410_1.in","r",stdin);
freopen("P5410.out","w",stdout);
}
int main(){
//file();
scanf("%s%s",s+1,t+1);
m=strlen(s+1),n=strlen(t+1);
init();
exKMP();
long long ans1=0,ans2=0;
for(int i=1;i<=n;++i) ans1^=1ll*i*(nxt[i]+1);
for(int i=1;i<=m;++i) ans2^=1ll*i*(ext[i]+1);
printf("%lld\n%lld\n",ans1,ans2);
return 0;
}
SAM
点击查看代码
inline int newpos(std::array nson,int nlen){return ++ptot,len[ptot]=nlen,swap(son[ptot],nson),ptot;}
inline void insert(int c){
int p=lastpos;int u=newpos(boom,len[p]+1);cnt[u]=1;
while(p&&!son[p][c]) son[p][c]=u,p=nxt[p];
if(!p) return lastpos=u,nxt[u]=1,void();
int d=son[p][c];
if(len[d]==len[p]+1) nxt[u]=d;
else{
int v=newpos(son[d],len[p]+1);
nxt[v]=nxt[d],nxt[d]=v,nxt[u]=v;
while(p&&son[p][c]==d) son[p][c]=v,p=nxt[p];
}
lastpos=u;
}
图论
网络流
最大流
点击查看代码
const int N=10000+13;
struct Edge{int v,w,nxt;}e[N*5];
int n,m,s,t,lim,to[N],xx[N],yy[N],uu[N],vv[N],deg[N],h[N],tot=1,ad[N];
inline void add(int u,int v,int w){
e[++tot]=(Edge){v,w,h[u]};h[u]=tot;
e[++tot]=(Edge){u,0,h[v]};h[v]=tot;
}
int dep[N],cur[N];
bool vis[N];
inline bool bfs(){
memset(dep,0x7f,sizeof(dep));
memcpy(cur,h,sizeof(h));
memset(vis,0,sizeof(vis));
std::queueq;
q.push(t),dep[t]=0,vis[t]=1;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=h[u];i;i=e[i].nxt){
int v=e[i].v,w=e[i^1].w;
if(!vis[v]&&w) dep[v]=dep[u]+1,vis[v]=1,q.push(v);
}
}
return vis[s];
}
ll dfs(int u,ll minw){
if(u==t||!minw) return minw;
ll f,flow=0;
for(int i=cur[u];i;i=e[i].nxt){
cur[u]=i;
int v=e[i].v,w=e[i].w;
if(dep[u]==dep[v]+1&&(f=dfs(v,min(minw,(ll)w)))){
minw-=f,flow+=f,e[i].w-=f,e[i^1].w+=f;
if(!minw) break;
}
}
return flow;
}
inline ll dinic(){
ll flow=0;
while(bfs()) flow+=dfs(s,INF);
return flow;
}
int main(){
read(n),read(m),read(s),read(t);
for(int i=1;i<=m;i++){
int u,v,w;read(u),read(v),read(w);
add(u,v,w);
add(v,u,0);
}
println(dinic());
return 0;
}
费用流
点击查看代码
#include
#include
#include
#include
#define re register
using namespace std;
const int N=5000+21,M=50000+21,INF=0x3f3f3f3f;
struct Edge{int u,v,f,w,nxt;}e[M*2];
int h[N],dist[N],last[N],flow[N],pre[N];
bool vis[N];
int n,m,s,t,tot=1;
inline void add(re int u,re int v,re int f,re int w){
e[++tot]=(Edge){u,v,f,w,h[u]};
h[u]=tot;
}
bool spfa(){
memset(dist,0x3f,sizeof(dist));
memset(vis,0,sizeof(vis));
memset(flow,0x3f,sizeof(flow));
pre[t]=-1;
queueq;
q.push(s);
vis[s]=1;
dist[s]=0;
while(!q.empty()){
re int u=q.front();
q.pop();
vis[u]=0;
for(re int i=h[u];i;i=e[i].nxt){
re int v=e[i].v,w=e[i].w,f=e[i].f;
if(f&&dist[v]>dist[u]+w){
dist[v]=dist[u]+w;
flow[v]=min(flow[u],f);
pre[v]=u;
last[v]=i;
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
return pre[t]!=-1;
}
void mcmf(){
re int maxflow=0,mincost=0;
while(spfa()){
maxflow+=flow[t];
mincost+=flow[t]*dist[t];
re int now=t;
while(now!=s){
e[last[now]].f-=flow[t];
e[last[now]^1].f+=flow[t];
now=pre[now];
}
}
printf("%d %d\n",maxflow,mincost);
}
int main(){
scanf("%d%d%d%d",&n,&m,&s,&t);
for(re int i=1;i<=m;++i){
re int u,v,f,w;
scanf("%d%d%d%d",&u,&v,&f,&w);
add(u,v,f,w);
add(v,u,0,-w);
}
mcmf();
return 0;
}
数据结构
LCT
点击查看代码
#include
#include
using namespace std;
const int N=1e5+13;
inline void swap(int &x,int &y){x^=y^=x^=y;}
int n,m,a[N];
struct Link_Cut_Tree{
struct Stack{
int s[N],t;
inline void clear(){t=0;}
Stack(){clear();}
inline void push(int x){s[++t]=x;}
inline int top(){return s[t];}
inline void pop(){--t;}
inline bool empty(){return !t;}
};
int fa[N],val[N],ch[N][2];bool tag[N];
inline void refresh(int x){val[x]=a[x]^val[ch[x][0]]^val[ch[x][1]];}
inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
inline bool chk(int x){return ch[fa[x]][1]==x;}
inline void rotate(int x){
int f=fa[x],gf=fa[f],k=chk(x),w=ch[x][k^1];
fa[x]=gf;if(!isroot(f)) ch[gf][chk(f)]=x;
if(w) fa[w]=f;ch[f][k]=w;
fa[f]=x;ch[x][k^1]=f;
refresh(f),refresh(x);
}
inline void pushdown(int x){
if(!tag[x]) return;
tag[ch[x][0]]^=1,tag[ch[x][1]]^=1,tag[x]=0;
swap(ch[x][0],ch[x][1]);
}
inline void splay(int x){
Stack st;
int p=x;
while(!isroot(p)) st.push(p),p=fa[p];
st.push(p);
while(!st.empty()) pushdown(st.top()),st.pop();
while(!isroot(x)){
int f=fa[x],gf=fa[f];
if(!isroot(f)){
if(chk(f)==chk(x)) rotate(f);
else rotate(x);
}
rotate(x);
}
}
inline void access(int x){
for(int p=0;x;p=x,x=fa[x]) splay(x),ch[x][1]=p,refresh(x);
}
inline void makeroot(int x){
access(x);
splay(x);
tag[x]^=1;
}
inline int findroot(int x){
access(x);
splay(x);
while(ch[x][0]) x=ch[x][0];
return x;
}
inline void split(int x,int y){
makeroot(x);
access(y);
splay(y);
}
inline void link(int x,int y){
makeroot(x);
if(findroot(y)!=x) fa[x]=y;
}
inline void cut(int x,int y){
split(x,y);
if(ch[y][0]==x&&!ch[x][1]) fa[x]=ch[y][0]=0;
}
inline void modify(int x,int y){
access(x);
splay(x);
a[x]=y,refresh(x);
}
}T;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
while(m--){
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
switch(op){
case 0:{T.split(x,y);printf("%d\n",T.val[y]);break;}
case 1:{T.link(x,y);break;}
case 2:{T.cut(x,y);break;}
case 3:{T.modify(x,y);break;}
}
}
return 0;
}
fhqtreap
点击查看代码
#include
#include
#include
#include
inline int rd(){
int res=0,flag=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')flag=-1;
for(;isdigit(c);c=getchar())res=(res<<1)+(res<<3)+(c-'0');
return res*flag;
}
void wt(int x){if(x<0)putchar('-'),x=-x;if(x>9)wt(x/10);putchar(x%10+'0');}
std::mt19937 rnd(std::chrono::system_clock::now().time_since_epoch().count());
const int N=1e5+13;
int n,rt,tot;
struct Fhqtreap{int ls,rs,siz,val,prio;}t[N];
#define ls(p) t[p].ls
#define rs(p) t[p].rs
inline int newnode(int x){return t[++tot]=(Fhqtreap){0,0,1,x,(int)rnd()},tot;}
inline void refresh(int p){t[p].siz=t[ls(p)].siz+t[rs(p)].siz+1;}
int merge(int p,int q){
if(!p||!q) return p|q;
if(t[p].priot[ls(p)].siz+1) k-=t[ls(p)].siz+1,p=rs(p);
else return p;
}
}
int main(){
// freopen("P3369_6.in","r",stdin);
// freopen("P3369.out","w",stdout);
int T=rd();
while(T--){
int op=rd(),k=rd(),x,y,z;
switch(op){
case 1:{
split(rt,k,x,y);
rt=merge(merge(x,newnode(k)),y);
break;
}
case 2:{
split(rt,k-1,x,z);split(z,k,z,y);
rt=merge(merge(x,merge(ls(z),rs(z))),y);
break;
}
case 3:{
split(rt,k-1,x,y);
wt(t[x].siz+1),putchar('\n');
rt=merge(x,y);
break;
}
case 4:{
wt(t[kth(rt,k)].val),putchar('\n');
break;
}
case 5:{
split(rt,k-1,x,y);
wt(t[kth(x,t[x].siz)].val),putchar('\n');
rt=merge(x,y);
break;
}
case 6:{
split(rt,k,x,y);
wt(t[kth(y,1)].val),putchar('\n');
rt=merge(x,y);
break;
}
}
}
return 0;
}
可持久化fhqtreap
点击查看代码
#include
#include
#include
#include
using namespace std;
const int N=5e5+13,logN=40+13;
int INF=2147483647;
struct Fhqtreap{int siz,ls,rs,prio,val;}t[N*logN];
typedef Fhqtreap Fhq;
int n,tot,rt[N];
inline int newnode(int v){t[++tot]=(Fhq){1,0,0,rand(),v};return tot;}
inline void refresh(int p){t[p].siz=t[t[p].ls].siz+t[t[p].rs].siz+1;}
int merge(int p,int q){
if(!p||!q) return p+q;
int now=++tot;
if(t[p].priot[t[p].ls].siz+1) k-=t[t[p].ls].siz+1,p=t[p].rs;
else return p;
}
}
int main(){
srand(time(NULL));
scanf("%d",&n);
for(int i=1,v,op,k,x,y,z;i<=n;++i,x=y=z=0){
scanf("%d%d%d",&v,&op,&k);rt[i]=rt[v];
switch(op){
case 1:{
split(rt[i],k,x,y);
rt[i]=merge(merge(x,newnode(k)),y);
break;
}
case 2:{
split(rt[i],k,x,z);
split(x,k-1,x,y);
y=merge(t[y].ls,t[y].rs);
rt[i]=merge(merge(x,y),z);
break;
}
case 3:{
split(rt[i],k-1,x,y);
printf("%d\n",t[x].siz+1);
rt[i]=merge(x,y);
break;
}
case 4:{
printf("%d\n",t[kth(rt[i],k)].val);
break;
}
case 5:{
split(rt[i],k-1,x,y);
if(!x) printf("%d\n",-INF);
else printf("%d\n",t[kth(x,t[x].siz)].val);
rt[i]=merge(x,y);
break;
}
case 6:{
split(rt[i],k,x,y);
if(!y) printf("%d\n",INF);
else printf("%d\n",t[kth(y,1)].val);
rt[i]=merge(x,y);
break;
}
}
}
return 0;
}
笛卡尔树
点击查看代码
#include
#include
#define rint register int
using namespace std;
inline int rd(){
int res=0;char c=getchar();
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())res=(res<<1)+(res<<3)+(c-'0');
return res;
}
const int N=1e7+13;
int n,a[N],s[N],top,L[N],R[N];
int main(){
n=rd();
for(rint i=1;i<=n;++i){
a[i]=rd();rint pos=top;
while(pos&&a[s[pos]]>a[i]) --pos;
if(pos) R[s[pos]]=i;
if(pos
虚树
点击查看代码
inline void build(){
st.clear();Tot=0;
sort(a+1,a+k+1,cmp);
st.push(1);
for(int i=1;i<=k;++i){
int t=lca(a[i],st.top());
if(t!=st.top()){
while(st.t>1&&id[t]
Segmenttree beats
点击查看代码
#include
#include
using namespace std;
typedef long long ll;
inline int max(const int &a,const int &b){return a>b?a:b;}
inline int min(const int &a,const int &b){return a9)wt(x/10);putchar(x%10+'0');}
const int N=5e5+13,INF=0x3f3f3f3f;
struct SegTree{int l,r,maxx,premax,se,cnt,add,preadd,addmax,preaddmax;ll sum;}t[N<<2];
int n,m;
#define ls p<<1
#define rs p<<1|1
#define mid ((t[p].l+t[p].r)>>1)
inline void refresh(int p){
t[p].sum=t[ls].sum+t[rs].sum;
t[p].premax=max(t[ls].premax,t[rs].premax);
if(t[ls].maxx>t[rs].maxx) t[p].maxx=t[ls].maxx,t[p].cnt=t[ls].cnt,t[p].se=max(t[ls].se,t[rs].maxx);
else if(t[ls].maxx==t[rs].maxx) t[p].maxx=t[ls].maxx,t[p].cnt=t[ls].cnt+t[rs].cnt,t[p].se=max(t[ls].se,t[rs].se);
else t[p].maxx=t[rs].maxx,t[p].cnt=t[rs].cnt,t[p].se=max(t[ls].maxx,t[rs].se);
}
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){t[p].sum=t[p].maxx=t[p].premax=rd(),t[p].se=-INF,t[p].cnt=1;return;}
build(ls,l,mid);build(rs,mid+1,r);
refresh(p);
}
inline void pushup(int p,int x,int px,int x_m,int px_m){
t[p].sum+=1ll*t[p].cnt*x_m+1ll*(t[p].r-t[p].l+1-t[p].cnt)*x;
t[p].premax=max(t[p].premax,t[p].maxx+px_m);
t[p].preadd=max(t[p].preadd,t[p].add+px);
t[p].preaddmax=max(t[p].preaddmax,t[p].addmax+px_m);
t[p].add+=x,t[p].addmax+=x_m,t[p].maxx+=x_m;
if(t[p].se!=-INF) t[p].se+=x;
}
inline void pushdown(int p){
int tmp=max(t[ls].maxx,t[rs].maxx);
if(t[ls].maxx==tmp) pushup(ls,t[p].add,t[p].preadd,t[p].addmax,t[p].preaddmax);
else pushup(ls,t[p].add,t[p].preadd,t[p].add,t[p].preadd);
if(t[rs].maxx==tmp) pushup(rs,t[p].add,t[p].preadd,t[p].addmax,t[p].preaddmax);
else pushup(rs,t[p].add,t[p].preadd,t[p].add,t[p].preadd);
t[p].add=t[p].preadd=t[p].addmax=t[p].preaddmax=0;
}
void update(int p,int l,int r,int x){
if(l<=t[p].l&&t[p].r<=r) return pushup(p,x,x,x,x);
pushdown(p);
if(l<=mid) update(ls,l,r,x);
if(r>mid) update(rs,l,r,x);
refresh(p);
}
void modify(int p,int l,int r,int x){
if(x>=t[p].maxx) return;
if(l<=t[p].l&&t[p].r<=r&&x>t[p].se) return pushup(p,0,0,x-t[p].maxx,x-t[p].maxx);
pushdown(p);
if(l<=mid) modify(ls,l,r,x);
if(r>mid) modify(rs,l,r,x);
refresh(p);
}
ll query_sum(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r) return t[p].sum;
pushdown(p);ll res=0;
if(l<=mid) res+=query_sum(ls,l,r);
if(r>mid) res+=query_sum(rs,l,r);
return res;
}
int query_max(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r) return t[p].maxx;
pushdown(p);int res=-INF;
if(l<=mid) res=max(res,query_max(ls,l,r));
if(r>mid) res=max(res,query_max(rs,l,r));
return res;
}
int query_premax(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r) return t[p].premax;
pushdown(p);int res=-INF;
if(l<=mid) res=max(res,query_premax(ls,l,r));
if(r>mid) res=max(res,query_premax(rs,l,r));
return res;
}
inline void file(){
freopen("P6242_1.in","r",stdin);
freopen("P6242.out","w",stdout);
}
int main(){
//file();
n=rd(),m=rd();
build(1,1,n);
while(m--){
int op,l,r,x;
op=rd(),l=rd(),r=rd();
switch(op){
case 1:x=rd();update(1,l,r,x);break;
case 2:x=rd();modify(1,l,r,x);break;
case 3:printf("%lld\n",query_sum(1,l,r));break;
case 4:printf("%d\n",query_max(1,l,r));break;
case 5:printf("%d\n",query_premax(1,l,r));break;
}
}
return 0;
}
李超树
点击查看代码
#include
#include
#include
using namespace std;
const int N=40000+13,M=1e5+13;
const double eps=1e-10;
struct Segment{double k,b;}a[M];
struct Node{
int id;double y;
bool operator<(const Node &a)const{
if(fabs(y-a.y)a.id;
return y>1)
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r) return;
build(ls,l,mid);build(rs,mid+1,r);
}
void update(int p,int l,int r,int id){
if(l<=t[p].l&&t[p].r<=r){
if(!t[p].id){t[p].id=id;return;}
if(t[p].l==t[p].r){
if(val(id,t[p].l)>val(t[p].id,t[p].l)) t[p].id=id;
return;
}
if(fabs(a[id].k-a[t[p].id].k)val(t[p].id,mid)) t[p].id=id;
}
else if(a[id].k>a[t[p].id].k){
if(val(id,mid)>val(t[p].id,mid)){
update(ls,l,r,t[p].id);
t[p].id=id;
}
else update(rs,l,r,id);
}
else{
if(val(id,mid)>val(t[p].id,mid)){
update(rs,l,r,t[p].id);
t[p].id=id;
}
else update(ls,l,r,id);
}
return;
}
if(l<=mid) update(ls,l,r,id);
if(r>mid) update(rs,l,r,id);
}
Node query(int p,int x){
Node res=(Node){t[p].id,val(t[p].id,x)};
if(t[p].l==t[p].r) return res;
return max(res,x<=mid?query(ls,x):query(rs,x));
}
int main(){
//freopen("P4097_1.in.txt","r",stdin);
//freopen("P4097.out","w",stdout);
build(1,1,n);
scanf("%d",&m);int lastans=0;
while(m--){
int op,x0,y0,x1,y1,x;
scanf("%d",&op);
if(op){
scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
x0=(x0+lastans-1)%n+1,x1=(x1+lastans-1)%n+1;
y0=(y0+lastans-1)%lim+1,y1=(y1+lastans-1)%lim+1;
if(x0>x1) swap(x0,x1),swap(y0,y1);
int id=add(x0,y0,x1,y1);
update(1,x0,x1,id);
}
else{
scanf("%d",&x);x=(x+lastans-1)%n+1;
Node ans=query(1,x);
printf("%d\n",(lastans=ans.id));
}
}
return 0;
}