模板搜集整理

本文深入探讨了数据结构中的并查集、线段树(包括区间加法和乘法)、图论算法(如Kruskal和Prim最小生成树,Floyd和Dijkstra最短路)以及字符串处理中的字符串Hash。此外,还介绍了快速读写、减少I/O时间等实用技巧。
摘要由CSDN通过智能技术生成

1.数据结构

1.1 并查集

int find(int x){
	if(f[x]==x) return x;
    return f[x]=find(f[x]);
}

1.2 线段树

1.2.1 线段树(区间加法)

struct tree{                   //树结构体
	int l,r;
	unsigned long long sum;
	unsigned long long add;
}t[maxn*4];

void build(int p,int l,int r){    //建树
	t[p].l=l,t[p].r=r;
	if(l==r){
		t[p].sum=a[l];
		return;
	}
	int mid=(l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	t[p].sum=t[p*2].sum+t[p*2+1].sum;
}

void spread(int p){               //打标记
	if(t[p].add){
		t[p*2].sum+=(t[p*2].r-t[p*2].l+1)*t[p].add;
		t[p*2+1].sum+=(t[p*2+1].r-t[p*2+1].l+1)*t[p].add;
		t[p*2].add+=t[p].add;
		t[p*2+1].add+=t[p].add;
		t[p].add=0;
	}
}

void change(int p,int l,int r,unsigned long long v){    //更新
	if(l<=t[p].l&&r>=t[p].r){
		t[p].sum+=(t[p].r-t[p].l+1)*v;
		t[p].add+=v;
		return;
	}
	spread(p);
	int mid=(t[p].l+t[p].r)/2;
	if(l<=mid) change(p*2,l,r,v);
	if(r>mid) change(p*2+1,l,r,v);
	t[p].sum=t[p*2].sum+t[p*2+1].sum;
}

unsigned long long ask(int p,int l,int r){              //区间查询
	if(l<=t[p].l&&r>=t[p].r) return t[p].sum;
	spread(p);
	int mid=(t[p].l+t[p].r)/2;
	unsigned long long val=0;
	if(l<=mid) val+=ask(p*2,l,r);
	if(r>mid) val+=ask(p*2+1,l,r);
	return val;
}

1.2.2 线段树(区间乘法)

struct tree{
	int l,r;
	long long sum;
	long long mu;
	long long add;
}t[maxn*4];
long long a[maxn];
long long n,m,x,y,k,p,mod;
inline void build(long long p,long long l,long long r){
	t[p].l=l,t[p].r=r,t[p].mu=1;
	if(l==r){
		t[p].sum=a[l]%mod;
		return;
	}
	long long mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
inline void spread(long long p){
	t[p*2].sum=(t[p].mu*t[p*2].sum+((t[p*2].r-t[p*2].l+1)*t[p].add)%mod)%mod;
	t[p*2+1].sum=(t[p].mu*t[p*2+1].sum+((t[p*2+1].r-t[p*2+1].l+1)*t[p].add)%mod)%mod;
	t[p*2].mu=(t[p*2].mu*t[p].mu)%mod;
	t[p*2+1].mu=(t[p*2+1].mu*t[p].mu)%mod;
	t[p*2].add=(t[p*2].add*t[p].mu+t[p].add)%mod;
	t[p*2+1].add=(t[p*2+1].add*t[p].mu+t[p].add)%mod;
	t[p].mu=1,t[p].add=0; 
}
inline void change1(long long p,long long l,long long r,long long w){
	if(l<=t[p].l&&r>=t[p].r){
		t[p].add=(t[p].add+w)%mod;
		t[p].sum=(t[p].sum+(t[p].r-t[p].l+1)*w)%mod;
		return;
	}
	spread(p);
	t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
	long long mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) change1(p*2,l,r,w);
	if(r>mid) change1(p*2+1,l,r,w);
	t[p].sum=(t[p*2].sum+t[p*2+1].sum)%mod;
}
inline void change2(long long p,long long l,long long r,long long w){
	if(l<=t[p].l&&r>=t[p].r){
		t[p].add=(t[p].add*w)%mod;
		t[p].mu=(t[p].mu*w)%mod;
		t[p].sum=(t[p].sum*w)%mod;
		return;
	}
	spread(p);
	long long mid=(t[p].l+t[p].r)>>1;
	if(l<=mid) change2(p*2,l,r,w);
	if(r>mid) change2(p*2+1,l,r,w);
	t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
inline long long ask(long long p,long long l,long long r){
	if(l<=t[p].l&&r>=t[p].r) return t[p].sum%mod;
	spread(p);
	long long mid=(t[p].l+t[p].r)>>1;
	long long val=0;
	if(l<=mid) val+=ask(p*2,l,r),val%=mod;
	if(r>mid) val+=ask(p*2+1,l,r),val%=mod;
	return val%mod;
}

1.3 树状数组(暂无)

1.4 树链剖分(暂无)

1.5 莫队

const int maxn=1000005;
int cnt[maxn],a[maxn],belong[maxn];
int n,m,now,size,bnum;
int ans[maxn];
struct data{
	int l,r,id;
}q[maxn];
int cmp(data a,data b){
	return (belong[a.l]^belong[b.l])?belong[a.l]<belong[b.l]:((belong[a.l]&1)?a.r<b.r:a.r>b.r);
}
int main(){
	n=read();
	size=sqrt(n);
	bnum=ceil((double)n/size);
	for(int i=1;i<=bnum;++i)
	 for(int j=(i-1)*size+1;j<=i*size;++j) belong[j]=i;
	for(int i=1;i<=n;++i) a[i]=read();
	m=read();
	for(int i=1;i<=m;++i){
		q[i].l=read(),q[i].r=read();
		q[i].id=i;
	}
	int l=l,r=0;
	sort(q+1,q+m+1,cmp);
	for(int i=1;i<=m;++i){
		int ql=q[i].l,qr=q[i].r;
		while(l>ql) l--,now+=!cnt[a[l]],cnt[a[l]]++;
		while(r<qr) r++,now+=!cnt[a[r]],cnt[a[r]]++;
		while(l<ql) cnt[a[l]]--,now-=!cnt[a[l]],l++;
		while(r>qr) cnt[a[r]]--,now-=!cnt[a[r]],r--;
		ans[q[i].id]=now;
	}
	for(int i=1;i<=m;++i) print(ans[i]),putchar('\n');
	return 0;
}

2.图论

2.1 Kruskal(最小生成树)

struct data{
	int u,v,w;
}e[500005];
bool cmp(data a,data b){
	return a.w<b.w;
}
int find(int x){
	if(x==f[x]) return x;
	return f[x]=find(f[x]);
}
void kruskal(){
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=m;++i){
		int eu=find(e[i].u),ev=find(e[i].v);
		if(eu==ev) continue;
		ans+=e[i].w;
		f[ev]=eu;
		if(++cnt==n-1) break;
	}
}

2.2 Prim(最小生成树)

struct node{
	int next,to,w;
}e[5000005];
int dis[5005],head[5005],tot,n,ans,cnt,now=1;
bool vis[5005]={0,1};
void add(int u,int v,int w){
	e[++cnt].to=v;
	e[cnt].w=w;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int prim(){
	for(register int i=2;i<=n;++i){
		dis[i]=maxn;
	}
	for(register int i=head[1];i!=-1;i=e[i].next){
		dis[e[i].to]=min(dis[e[i].to],e[i].w);
	}
	while(++tot<n){
		int minn=maxn;
		for(register int i=1;i<=n;++i){
			if(!vis[i]&&dis[i]<minn){
				minn=dis[i];
				now=i;
			}
		}
		vis[now]=1;
		ans+=minn;
		for(register int i=head[now];i!=-1;i=e[i].next){
			if(!vis[e[i].to]&&dis[e[i].to]>e[i].w)
			dis[e[i].to]=e[i].w;
		}
	}
	return ans;
} 

2.3 Floyd(最短路(无法处理负权边))

void floyd(){ //复杂度n^3
	for(int k=1;k<=n;++k){
		for(int i=1;i<=n;++i){
			if(i==k||a[i][k]==inf) continue;
			for(int j=1;j<=n;++j)
			a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
		}
	}
}

2.4 Dijkstra(最短路(可处理负权边))

struct data{
	int w,to,next;
}e[500005];
int cnt,n,m,s;
int head[maxn],vis[maxn],dis[maxn];
void add(int u,int v,int w){
	e[++cnt].to=v;
	e[cnt].w=w;
	e[cnt].next=head[u];
	head[u]=cnt;
}
struct node{
	int w,now;
	inline bool operator < (const node &x) const
	{
		return w>x.w;
	}
};
priority_queue<node>q;
void dijkstra(){         //n*logn
	for(int i=1;i<=n;++i) dis[i]=inf;
    dis[s]=0;
    q.push((node){0,s});
    while(!q.empty()){
    	node x=q.top();
    	q.pop();
    	int u=x.now;
    	if(vis[u]) continue;
    	vis[u]=1;
    	for(int i=head[u];i;i=e[i].next){
    		int v=e[i].to;
    		if(dis[v]>dis[u]+e[i].w){
    			dis[v]=dis[u]+e[i].w;
    			q.push((node){dis[v],v});
			}
		}
	}
}

2.5 LCA(最近公共祖先)(暂无)

2.6 拓补排序(暂无)

3.字符串

3.1 字符串hash

//单hash
const unsigned long long base=131;
const unsigned long long mod=212370440130137957ll;
int n;
unsigned long long a[10005],ans=1;
char c[10005];
unsigned long long hash1(char c[]){
	int len=strlen(c);
	unsigned long long ans=0;
	for(int i=0;i<len;++i){
		ans=(ans*base+c[i])%mod;
	}
	return ans;
}

3.2 KMP(暂无)

3.3 mannachar(暂无)

4.杂项

4.1 快读

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<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}

4.2 快写

inline void print(int x){
	if(x<0){
		putchar('-');
		x=-x;
	}
	if(x>9){
		print(x/10);	
	}
	putchar(x%10+'0');
}

4.3 减少cin、cout耗费时间

std::ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);

4.4 欧拉筛

void ols(int n){
	memset(vis,1,sizeof(vis));
	vis[1]=0;
	for(register int i=2;i<=n;++i){
		if(vis[i]==1) ss[++cnt]=i;
		for(register int j=1;j<=cnt&&i*ss[j]<=n;++j){
			vis[i*ss[j]]=0;
			if(i%ss[j]==0) break;
		}
	}
}

4.5 最大公约数

int gcd(int a,int b){
	return b?(gcd(b,a%b)):a;
}

4.6 int128

void scan(__int128 &x){
	x=0;
	int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	x*=f;
}
void _print(__int128 x){
	if(x>9) _print(x/10);
	putchar(x%10+'0');
}
void print(__int128 x){
	if(x<0) x=-x,putchar('-');
	_print(x);
}

4.7 快速幂+龟速乘

long long gsc(long long a,long long b,long long m){
	long long f=1,sum=0;
	if(a<0) f=-1,a=-a;
	if(b<0) f*=-1,b=-b;
	while(a){
		if(a&1){
			sum=(sum+b)%m;
		}
		b=b*2%m;
		a>>=1;
	}
	return sum*f%m; 
}
long long ksm(long long x,long long n,long long m){
	long long ans=1;
	while(n){
		if(n&1){
			ans=gsc(ans,x,m);
			n--;
		}
		x=gsc(x,x,m);
		n/=2;
	}
	return ans%m;
}

AFO了,有缘再更……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值