templates

liyixin發表於2024-11-26

templates

前言

2024.11.25 此文用於整理板子

字串

KMP

namespace KMP {
    constexpr int N=1e6+7;
    char s[N],t[N];
    int lens,lent;
    int nxt[N];// 字尾 i 的 border 長度
    void main() {
        sf("%s%s",s+1,t+1);
        lens=strlen(s+1), lent=strlen(t+1);
        rep(i,2,lent) {
            int &p=nxt[i]=nxt[i-1];
            while(p && t[i]!=t[p+1]) p=nxt[p];
            if(t[i]==t[p+1]) ++p;
        }
        int itt=0;// 已經匹配了 itt 位
        rep(i,1,lens) {
            while(itt && s[i]!=t[itt+1]) itt=nxt[itt];
            if(s[i]==t[itt+1]) ++itt;
            if(itt==lent) pf("%d\n",i-lent+1);
        }
        rep(i,1,lent) pf("%d ",nxt[i]);
    }
}

資料結構

線段樹

zkw 線段樹

struct zkw {
	int p;
	ll sum[N<<2],tag[N<<2];
	void pushup(int u,int siz) { sum[u]=sum[u<<1]+sum[u<<1|1]+tag[u]*siz; }
	void build() {
		p=1;
		while(p-2<n) p<<=1;
		rep(i,1,n) sum[p+i]=a[i];
		per(i,p-1,1) sum[i]=sum[i<<1]+sum[i<<1|1];
	}
	void update(int l,int r,ll x) {
		int L=p+l-1,R=p+r+1;
		int siz=1;
		while(L^R^1) {
			if((L&1)^1) sum[L^1]+=x*siz, tag[L^1]+=x;
			if(R&1) sum[R^1]+=x*siz, tag[R^1]+=x;
			L>>=1, R>>=1, siz<<=1;
			pushup(L,siz),pushup(R,siz);
		} 
		for(L>>=1,siz<<=1;L;L>>=1,siz<<=1) pushup(L,siz);
	}
	ll query(int l,int r) {
		ll s=0;
		int L=p+l-1,R=r+p+1;
		int sizl=0,sizr=0,siz=1;
		while(L^R^1) {
			if((L&1)^1) s+=sum[L^1], sizl+=siz;
			if(R&1) s+=sum[R^1], sizr+=siz;
			L>>=1, R>>=1, siz<<=1;
			s+=tag[L]*sizl+tag[R]*sizr;
		}
		for(L>>=1,sizl+=sizr;L;L>>=1) s+=tag[L]*sizl;
		return s;
	}
};

樹鏈剖分

重鏈剖分

struct tree {
	int fa[N],siz[N],gson[N];
	int st[30][N];
	int lcamin(int u,int v) { return dfn[u]<dfn[v] ? u : v; }
	int getlca(int u,int v) {
		if(u==v) return u;
		int mn=min(dfn[u],dfn[v])+1, mx=max(dfn[u],dfn[v]);
		int lg=__lg(mx-mn+1);
		return lcamin(st[lg][mn],st[lg][mx-(1<<lg)+1]);
	}
	int dfn[N],eddfn[N],cnt,idfn[N];
	int top[N];
	void dfs(int u,int f) {
		fa[u]=f;
		siz[u]=1;
		for(int i=head[u]; i; i=e[i].ne) {
			int v=e[i].to;
			if(v==f) continue;
			dfs(v,u);
			siz[u]+=siz[v];
			if(siz[v]>siz[gson[u]]) gson[u]=v;
		}
	}
	void dfs(int u) {
		dfn[u]=eddfn[u]=++cnt;
		idfn[cnt]=u;
		st[0][cnt]=fa[u];
		if(gson[u]) top[gson[u]]=top[u], dfs(gson[u]);
		_max(eddfn[u],eddfn[gson[u]]);
		for(int i=head[u]; i; i=e[i].ne) {
			int v=e[i].to;
			if(v==fa[u] || v==gson[u]) continue;
			top[v]=v, dfs(v);
			_max(eddfn[u],eddfn[v]);
		}
	}
	int tr[N<<2],tag[N<<2];
	int p;
	void build() {
		p=1;
		while(p-2<n) p<<=1;
		rep(i,1,n) tr[p+i]=a[idfn[i]];
		per(i,p-1,1) tr[i]=add(tr[i<<1],tr[i<<1|1]);
	}
	void init() {
		dfs(rt,0);
		top[rt]=rt;
		dfs(rt);
		int lg=__lg(n);
		rep(k,1,lg) for(int i=1;i+(1<<k)-1<=n;i++) st[k][i]=lcamin(st[k-1][i],st[k-1][i+(1<<(k-1))]);
		build();
	}
	void maketag(int u,int x,int siz) { _add(tr[u],1ll*x*siz%mod), _add(tag[u],x); }
	void pushup(int u,int siz) { tr[u]=add(add(tr[u<<1],tr[u<<1|1]),1ll*siz*tag[u]%mod); }
	void _update(int l,int r,int x) {
		l=p+l-1, r=p+r+1;
		int siz=1;
		while(l^r^1) {
			if((l&1)^1) maketag(l^1,x,siz);
			if(r&1) maketag(r^1,x,siz);
			l>>=1, r>>=1, siz<<=1;
			pushup(l,siz), pushup(r,siz);
		} 
		for(l>>=1, siz<<=1; l; l>>=1, siz<<=1) pushup(l,siz);
	}
	int _query(int l,int r) {
		l=p+l-1, r=p+r+1;
		int sizl=0,sizr=0,siz=1;
		int s=0;
		while(l^r^1) {
			if((l&1)^1) _add(s,tr[l^1]), sizl+=siz;
			if(r&1) _add(s,tr[r^1]), sizr+=siz;
			l>>=1, r>>=1, siz<<=1;
			_add(s,1ll*tag[l]*sizl%mod), _add(s,1ll*tag[r]*sizr%mod);
		}
		for(l>>=1, sizl+=sizr; l; l>>=1) _add(s,1ll*tag[l]*sizl%mod);
		return s;
	}
	void update(int u,int v,int x) {
		int lca=getlca(u,v);
		while(dfn[top[u]]>dfn[lca]) _update(dfn[top[u]],dfn[u],x), u=fa[top[u]];
		_update(dfn[lca],dfn[u],x);
		while(dfn[top[v]]>dfn[lca]) _update(dfn[top[v]],dfn[v],x), v=fa[top[v]];
		if(dfn[v]>=dfn[lca]+1) _update(dfn[lca]+1,dfn[v],x);
	}
	void update(int u,int x) {
		_update(dfn[u],eddfn[u],x);
	}
	int query(int u,int v) {
		int lca=getlca(u,v);
		int s=0;
		while(dfn[top[u]]>dfn[lca]) _add(s,_query(dfn[top[u]],dfn[u])), u=fa[top[u]];
		_add(s,_query(dfn[lca],dfn[u]));
		while(dfn[top[v]]>dfn[lca]) _add(s,_query(dfn[top[v]],dfn[v])), v=fa[top[v]];
		if(dfn[v]>=dfn[lca]+1) _add(s,_query(dfn[lca]+1,dfn[v]));
		return s;
	}
	int query(int u) {
		return _query(dfn[u],eddfn[u]);
	}
};

相關文章