$("head").append('')

板子

板子


快读


inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

欧拉筛


int n,cnt,vis[40005],prime[4005],phi[40005];
void euler(){
	//phi[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]){
			prime[++cnt]=i;
			//phi[i]=i-1;
		}
		for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
			vis[i*prime[j]]=1;
			if(i%prime[j]==0){
				//phi[i*prime[j]]=phi[i]*prime[j];
				break;
			}
			//phi[i*prime[j]]=phi[i]*phi[prime[j]];
		}
	}
}
//"//"后的为欧拉函数

同余

\(a\equiv b(\bmod m)=m|a-b=a-b=km\)

\(p=\lfloor \frac p i \rfloor \times +(p\%i)\)
\(p \equiv0 \pmod p\)
\(\lfloor \frac p i \rfloor \times i+(p\%i) \equiv 0 \pmod p\)
\(\lfloor \frac p i \rfloor + (p\%i)\times i^{-1}\equiv 0 \pmod p\)
\(\lfloor \frac p i \rfloor (p\%i)^{-1}+ i^{-1}\equiv 0 \pmod p\)
\(i^{-1} \equiv (p-\lfloor \frac p i \rfloor)\times(p\%i)^{-1} \pmod p\)


矩阵


#include<bits/stdc++.h> 
#define ll long long
using namespace std; 
const int mod=1e9+7;
struct Mat{
	#define int long long
	int a[105][105],r,c;
	Mat(int _r=0,int _c=0){
		r=_r,c=_c;memset(a,0,sizeof(a));
		if(c==0) c=r;
	}
	void unit(){
		memset(a,0,sizeof(a));
		for(int i=1;i<=r;i++) a[i][i]=1;
	}
	Mat operator+(const Mat&t)const{
		Mat ans=*this;
		for(int i=1;i<=r;i++){
			for(int j=1;j<=c;j++){
				ans.a[i][j]+=t.a[i][j];
			}
		}
		return ans;
	}
	Mat operator*(const Mat&t)const{
		Mat ans(r,t.c);
		int n=r,m=t.c;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				for(int k=1;k<=c;k++){
					ans.a[i][j]=(ans.a[i][j]+a[i][k]*t.a[k][j])%mod;
				}
			}
		}
		return ans;
	}
	Mat qpow(int b){
	    Mat ans(r,c),a=*this;
	    ans.unit();
	    while(b){
	    	if(b&1) ans=ans*a;
	    	a=a*a;
	    	b>>=1;
		}
		return ans;
	}
	void out(){
		for(int i=1;i<=r;i++){
			for(int j=1;j<=c;j++){
				cout<<a[i][j]<<" ";
			}
			cout<<"\n";
		}
	}
	void input(){
		for(int i=1;i<=r;i++){
			for(int j=1;j<=c;j++){
				cin>>a[i][j];
			}
		}
	}
	#undef int
};

链式前向星


struct node{
	int to,nxt,w;
}edge[N<<1];
int head[N],cnt=1;
void add(int u,int v,int w){
	edge[cnt].to=v;
	edge[cnt].nxt=head[u];
	edge[cnt].w=w;
	head[u]=cnt++;
}

bfs


void bfs(){
	qx.push(sx);qy.push(sy);
	vis[sx][sy]=1;
	while(!qx.empty()){
		int x=qx.front(),y=qy.front();
		qx.pop();qy.pop();
		for(int i=0;i<4;i++){
			int tx=x+dx[i],ty=y+dy[i];
			if(tx>n||tx<1||ty>m||ty<1) continue;
			if(vis[tx][ty]) continue;
			vis[tx][ty]=1;
			qx.push(tx);qy.push(ty);
		}
	}
}

最短路(Dijkstra)


const int INF=0x3f3f3f3f,N=2e5+5;
int n,m,s,t,cnt=1,dis[N],vis[N],head[N];
struct e{
	int to,nxt,w;
}edge[N];
struct node{
	int v,w;
	const bool operator<(const node &x)const{
		return w>x.w;
	}
};
priority_queue<node> q;
void dijkstra(){
	memset(dis,0x3f,sizeof(dis));
	dis[s]=0;q.push({s,0});
	while(!q.empty()){
		int u=q.top().v;q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to,w=edge[i].w;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				q.push({v,dis[v]});
			}
		}
	}
}

最短路(SPFA)


queue<int> q;
void spfa(){
	memset(dis,0x3f,sizeof(dis));
	dis[s]=0;q.push(s);vis[s]=1;
	while(!q.empty()){
		int u=q.front();q.pop();
		vis[u]=0;
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to,w=edge[i].w;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				if(!vis[v]) q.push(v);
			}
		}
	}
}

最小生成树(Kruskal)


int fa[5005],n,m,f,ans;
struct node{
	int x,y,z;
}a[200005];
bool cmp(node x,node y){
	return x.z<y.z;
}
int find(int x){
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}
void add(int x,int y,int k){
	int f1=find(x),f2=find(y);
	if(f1!=f2) fa[f1]=f2,n--,ans+=a[k].z;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>a[i].x>>a[i].y>>a[i].z;
	}
	sort(a+1,a+m+1,cmp);
	for(int i=1;i<=n;i++)
		fa[i]=i;
	for(int i=1;i<=m;i++){
		add(a[i].x,a[i].y,i);
		if(n==1) break;
	}
	return 0;
}

最小生成树(Prim)


void Prim(){
	for(int i=1;i<=n;i++) dis[i]=0x3f3f3f3f;
	dis[1]=0; q.push({1,0});
	while(!q.empty()){
		int u=q.top().v;q.pop();
		if(vis[u]) continue;
		vis[u]=1;ans+=dis[u];sum++;
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to,w=edge[i].w;
			if(vis[v]) continue;
			if(dis[v]>w){
				dis[v]=w;
				q.push({v,w});
			}
		}
	}
}

std容器清空


template<typename T>
void clear(T &x){
	T tmp;
	swap(x,tmp);
}

ST表


int n,m,f[100005][30];
int query(int l,int r){
	int k=log2(r-l+1);
	return max(f[l][k],f[r-(1<<k)+1][k]);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&f[i][0]);
	for(int j=1;(1<<j)<=n;j++)
		for(int i=1;i+(1<<j)-1<=n;i++)
			f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);
	while(m--){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",query(l,r));
	}
	return 0;
} 

线段树


const int N=1e5+5;
struct tree{
	int l,r,sum,laz;
}t[N<<2];
int n,m,a[N];
int ls(int p){
	return p<<1;
}
int rs(int p){
	return p<<1|1;
}
void pushup(int p){
	t[p].sum=t[ls(p)].sum+t[rs(p)].sum;
}
void pushdown(int p){
	t[ls(p)].sum+=t[p].laz*(t[ls(p)].r-t[ls(p)].l+1);
	t[rs(p)].sum+=t[p].laz*(t[rs(p)].r-t[rs(p)].l+1);
	t[ls(p)].laz+=t[p].laz;
	t[rs(p)].laz+=t[p].laz;
	t[p].laz=0;
}
void build(int p,int l,int r){
	t[p].l=l,t[p].r=r;
	if(t[p].l==t[p].r){
		t[p].sum=a[l];
		return ;
	}
	int mid=l+r>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	pushup(p);
}
void update(int p,int l,int r,int k){
	if(t[p].l>=l&&t[p].r<=r){
		t[p].sum+=(t[p].r-t[p].l+1)*k;
		t[p].laz+=k;
		return ;
	}
	pushdown(p);
	int mid=t[p].l+t[p].r>>1;
	if(l<=mid) update(ls(p),l,r,k);
	if(mid<r) update(rs(p),l,r,k);
	pushup(p);
}
int query(int p,int l,int r){
	if(t[p].l>=l&&t[p].r<=r){
		return t[p].sum;
	}
	pushdown(p);
	int ans=0;
	int mid=t[p].l+t[p].r>>1;
	if(l<=mid) ans+=query(ls(p),l,r);
	if(mid<r) ans+=query(rs(p),l,r);
	pushup(p);
	return ans;
}

FHQ Treap


struct tree{
	int ls,rs,val,rnk,sz;
}t[N];
int tot,root;
void update(int p){
	t[p].sz=t[t[p].ls].sz+t[t[p].rs].sz+1;
}
int add(int val){
	t[++tot].sz=1;
	t[tot].val=val;
	t[tot].rnk=rand();
	return tot;
}
void split(int p,int &a,int &b,int val){
	if(p==0){
		a=b=0;
		return ;
	}
	if(t[p].val<=val){
		a=p;
		split(t[p].rs,t[p].rs,b,val);
	}
	else{
		b=p;
		split(t[p].ls,a,t[p].ls,val);
	}
	update(p);
	return ;
}
void merge(int &p,int a,int b){
	if(a==0||b==0){
		p=a+b;
		return ;
	}
	if(t[a].rnk<t[b].rnk){
		p=a;
		merge(t[a].rs,t[a].rs,b);
	}
	else{
		p=b;
		merge(t[b].ls,a,t[b].ls);
	}
	update(p);
	return ;
}
void insert(int &p,int val){
	int a=0,b=0,cur=add(val);
	split(p,a,b,val);
	merge(a,a,cur);
	merge(p,a,b);
	return ;
}
void del(int &p,int val){
	int a=0,b=0,z=0;
	split(p,a,b,val);
	split(a,a,z,val-1);
	merge(z,t[z].ls,t[z].rs);
	merge(a,a,z);
	merge(p,a,b);
	return ;
}
int find_num(int p,int x){
    while(t[t[p].ls].sz+1!=x){
        if(t[t[p].ls].sz>=x)
            p=t[p].ls;
        else{
            x-=t[t[p].ls].sz+1;
            p=t[p].rs;
        }
    }
    return t[p].val;
}
int find_rank(int &p,int val){
    int a=0,b=0;
    split(p,a,b,val-1); 
    int tmp=t[a].sz+1;
    merge(p,a,b);
    return tmp;
}
int prev(int &p,int val){
    int a=0,b=0;
    split(p,a,b,val-1);
    int tmp=find_num(a,t[a].sz);
    merge(p,a,b);
    return tmp;
}
int suf(int &p, int val){
    int a=0,b=0;
    split(p,a,b,val);
    int tmp=find_num(b,1);
    merge(p,a,b);
    return tmp;
}

分块


const int N=1e6+5;
int a[N],b[N],l[1005],r[1005],belong[N],laz[1005];
int n,q,block,tot;
void build(){
	block=(int)sqrt(n);tot=n/block;
	if(n%block!=0) tot++;
	for(int i=1;i<=n;i++){
		belong[i]=(i-1)/block+1;b[i]=a[i];
	}
	for(int i=1;i<=tot;i++){
		l[i]=(i-1)*block+1;r[i]=i*block;
	}
	r[tot]=n;
	for(int i=1;i<=tot;i++){
		sort(b+l[i],b+r[i]+1);
	}
}
void change(int x,int y,int k){
	if(belong[x]==belong[y]){
		for(int i=x;i<=y;i++){
			a[i]+=k;
		}
		for(int i=l[belong[x]];i<=r[belong[x]];i++){
			b[i]=a[i];
		}
		sort(b+l[belong[x]],b+r[belong[x]]+1);
	}
	else{
		for(int i=x;i<=r[belong[x]];i++){
			a[i]+=k;
		}
		for(int i=l[belong[x]];i<=r[belong[x]];i++){
			b[i]=a[i];
		}
		sort(b+l[belong[x]],b+r[belong[x]]+1);
		for(int i=l[belong[y]];i<=y;i++){
			a[i]+=k;
		}
		for(int i=l[belong[y]];i<=r[belong[y]];i++){
			b[i]=a[i];
		}
		sort(b+l[belong[y]],b+r[belong[y]]+1);
		for(int i=belong[x]+1;i<=belong[y]-1;i++){
			laz[i]+=k;
		}
	}
}
int query(int x,int y,int k){
	int ans=0;
	if(belong[x]==belong[y]){
		for(int i=x;i<=y;i++){
			if(laz[belong[x]]+a[i]>=k) ans++;
		}
		return ans;
	}
	else{
		for(int i=x;i<=r[belong[x]];i++){
			 if(laz[belong[x]]+a[i]>=k) ans++;
		}
		for(int i=l[belong[y]];i<=y;i++){
			if(laz[belong[y]]+a[i]>=k) ans++;
		}
		for(int i=belong[x]+1;i<=belong[y]-1;i++){
			int ll=l[i],rr=r[i],sum=0;
			while(ll<=rr){
				int mid=ll+rr>>1;
				if(b[mid]+laz[i]>=k) rr=mid-1,sum=r[i]-mid+1;
				else ll=mid+1;
			}
			ans+=sum;
		}
		return ans;
	}
}

最近公共祖先(LCA) (树剖版)


const int N=5e5+5;
int fa[N],top[N],dep[N],sz[N],wc[N];
void dfs1(int u,int f){
	fa[u]=f;sz[u]=1;dep[u]=dep[f]+1;
	for(int i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(v==f) continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[wc[u]]) wc[u]=v;
	}
}
void dfs2(int u,int Top){
	top[u]=Top;
	if(wc[u]) dfs2(wc[u],Top);
	for(int i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(v==fa[u]||v==wc[u]) continue;
		dfs2(v,v);
	}
}
int qry(int x,int y){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		x=fa[top[x]];
	}
	if(dep[x]<dep[y]) return x;
	return y;
}

Tarjan


const int N=1e5+5;
struct node{
	int to,nxt;
}edge[N]; 
int head[N],cnt=1;
void add(int u,int v){
	edge[cnt].to=v;
	edge[cnt].nxt=head[u];
	head[u]=cnt++;
}
int dfn[N],low[N],idx,sz[N],bel[N],tot;
bool ins[N];
stack<int> st;
void dfs(int u){
	low[u]=dfn[u]=++tot;
	st.push(u);
	ins[u]=1;
	for(int i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(!dfn[v]){
			dfs(v);
			low[u]=min(low[u],low[v]);
		}else if(ins[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if(low[u]==dfn[u]){
		int v;++idx;
		do{
			v=st.top();st.pop();
			bel[v]=idx;
			ins[v]=0;
			++sz[idx];
		}while(v!=u);
	}
}

字符串哈希


struct HASH{
	int sed,mod,h[N],pw[N];
	HASH(int ssed=128,int mmod=998244353){
		sed=ssed,mod=mmod;
		pw[0]=1;
		for(int i=1;i<N;i++) pw[i]=pw[i-1]*1ll*sed%mod;
	}
	void make(string s){
		h[0]=s[0]%mod;
		for(int i=1;i<s.size();i++){
			h[i]=(h[i-1]*1ll*sed%mod+s[i])%mod;
		}
	}
	void make(char *s){
		h[0]=s[0]%mod;
		for(int i=1;s[i];i++){
			h[i]=(h[i-1]*1ll*sed%mod+s[i])%mod;
		}
	}
	int get(int L,int R){
		if(!L) return h[R];
		return (h[R]-h[L-1]*1ll*pw[R-L+1]%mod+mod)%mod;
	}
	int get(int R){
		return h[R];
	}
};

KMP


void getNxet(char P[]){
	int i,j;//i遍历主串,j是border长度
	//j也是前部分border的最后一个字符的下标 
	for(Next[i]=j=0,i=2;P[i];i++){
		while(j&&P[i]!=P[j+1]) j=Next[j];//不相等跳border
		if(P[i]==P[j+1]) j++;//相等border长度+1 
		Next[i]=j;//记录s[1~i]这个前缀的border 
	}
} 
void KMP(char S[],char P[]){//主串S,模式串P 
	n=strlen(P+1);//获取模式串的长度 
	getNext(P);//先对模式串求每个前缀的border长度 
	int i,j,ans=0;
	for(j=0,i=1;S[i];i++){//开始匹配
	//j代表了模式串中匹配成功的长度 
		while(j&&S[i]!=P[j+1]) j=Next[j];//不相等跳border
		if(S[i]==P[j+1]) j++;//相等匹配成功长度+1
		if(j==n){//整个模式串都匹配成功 
			cout<<i-n+1<<"\n";//输出匹配成功的开头位置 
			j=Next[j];//允许重复跳border
			//不允许重复j=0 
		}
	} 
} 

int b[1000005];
string s1,s2;
int main(){
	cin>>s1>>s2;
	int len1=s1.size(),len2=s2.size(),j=0;
	for(int i=1;i<len2;i++){
		while(j>0&&s2[i]!=s2[j]) j=b[j-1];
		if(s2[j]==s2[i]) j++;
		b[i]=j;
	} j=0;
	for(int i=0;i<len1;i++){
		while(j>0&&s1[i]!=s2[j]) j=b[j-1];
		if(s2[j]==s1[i]) j++;
		if(j==len2) j=b[j-1];
	}
}

字典树


int trie[N][26],word[N],cnt[N];
string s;
int n,m,tot,ans;
void insert(string s){
	int u=0,res=0;
	int len=s.size();
	for(int i=0;i<len;i++){
		int a=s[i]-'a';
		if(trie[u][a]==0){
			trie[u][a]=++tot;
		}
		u=trie[u][a];
	}
	word[u]++;
}

manacher


int manacher(string &t){
	string s="$|";
	for(char c:t) s.push_back(c),s.push_back('|');
	int n=s.size(),r=0,pos=0,ans=0;s+='!';
	for(int i=1;i<n;i++){
		p[i]=(r>i?min(p[2*pos-i],r-i):1);
		while(s[i-p[i]]==s[i+p[i]]) p[i]++;
		if(i+p[i]>r) r=i+p[i],pos=i;
		ans=max(ans,p[i]-1);
	}
	return ans;
}
posted @ 2025-12-07 21:19  lain_yc  阅读(0)  评论(0)    收藏  举报
$("head").append('')