正放的瓶塞

导航

模板代码(后续补充)

int快读(可负数)

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

倍增ST表

for (int i=1;i<=n;i++) 
     f[0][i]=read();
for (int i=1;i<=21;i++) 
     for (int j=1;j+(1<<i)-1<=n;j++) 
           f[i][j]=max(f[i-1][j],f[i-1][j+(1<<(i-1))]);
while(m--) {
     l=read();r=read();
     len=log2(r-l+1);
     printf("%d\n",max(f[len][l],f[len][r-(1<<len)+1]));
      }

指针线段树

struct note {
	ll s,alazy;
	note *lson,*rson;
}pool[M<<1],*root=&pool[0];
void Build(note *tre,int l,int r) {
	if (l==r) {
	      tre->s=a[l];
	      return;
	}
	int mid=(l+r)>>1;
	tre->lson=&pool[++cnt];
	tre->rson=&pool[++cnt];
	Build(tre->lson,l,mid);
	Build(tre->rson,mid+1,r);
	tre->s=tre->lson->s + tre->rson->s;
}
inline void pushdown(note *tre,int l,int r) {
	if (!tre->alazy) return ;
	int mid=(l+r)>>1;
	tre->lson->s +=tre->alazy*(mid-l+1);
	tre->rson->s +=tre->alazy*(r-mid);
	tre->lson->alazy+=tre->alazy;
	tre->rson->alazy+=tre->alazy;
	tre->alazy=0;
}
void change(note *tre,int l,int r,int x,int y,int d) {
	if (x<=l&&y>=r) {
		tre->s+=(ll)d*(r-l+1);
		tre->alazy+=d;
		return;
	}
	pushdown(tre,l,r);
	int mid=(l+r)>>1;
	if (x<=mid) change(tre->lson,l,mid,x,y,d);
	if (y>mid) change(tre->rson,mid+1,r,x,y,d);
	tre->s=tre->lson->s +tre->rson->s;
}
ll query(note *tre,int l ,int r,int x,int y) {
	if (x<=l&&y>=r) return tre->s;
	pushdown(tre,l,r);
	int mid=(l+r)>>1;
	ll t1=0,t2=0;
	if (x<=mid) t1=query(tre->lson,l,mid,x,y);
	if (y>mid) t2=query(tre->rson,mid+1,r,x,y);
	return t1+t2;
}
int main() {
      scanf("%d%d",&n,&m);
      for (int i=1;i<=n;i++) scanf("%d",&a[i]);
      Build(root,1,n);
      while(m--) {
	      scanf("%d",&k);
	      if (k==1) {
		scanf("%d%d%d",&x,&y,&k);
		change(root,1,n,x,y,k);
	      }
	      else {
		scanf("%d%d",&x,&y);
		printf("%lld\n",query(root,1,n,x,y));
	      }
      }
      return 0;
}

数组线段树

inline ll lson(ll x) {return x<<1;}
inline ll rson(ll x) {return x<<1|1;}
inline void update(ll x) {c[x].sum=c[lson(x)].sum+c[rson(x)].sum;}
inline ll diss(ll x) {return c[x].r-c[x].l+1;}
inline ll mid(ll l,ll r) {return (l+r)>>1;}
inline void pushdown(ll x) {
	if (c[x].tag) {
		c[lson(x)].sum+=c[x].tag*diss(lson(x));
		c[rson(x)].sum+=c[x].tag*diss(rson(x));
		c[lson(x)].tag+=c[x].tag;
		c[rson(x)].tag+=c[x].tag;
		c[x].tag=0;
	}
}
void build(ll x,ll l,ll r) {
	c[x].l=l;c[x].r=r;
	if (l==r) {
		c[x].sum=a[l];
		return;
	}
	build(lson(x),l,mid(l,r));
	build(rson(x),mid(l,r)+1,r);
	update(x);
}
ll query(ll x,ll l,ll r) {
	if (c[x].l>=l&&c[x].r<=r)return c[x].sum;
	pushdown(x);
	ll mi=mid(c[x].l,c[x].r);
	ll ans=0;
	if (l<=mi)ans+=query(lson(x),l,r);
	if (r>mi) ans+=query(rson(x),l,r);
	return ans;
}

void change(ll x,ll l,ll r,ll d) {
	if (c[x].l>=l&&c[x].r<=r) {
		c[x].sum+=d*diss(x);
		c[x].tag+=d;
		return;
	}
	pushdown(x);
	ll mi=mid(c[x].l,c[x].r);
	if (l<=mi) change(lson(x),l,r,d);
	if (r>mi) change(rson(x),l,r,d);
	update(x);
}

快速幂

ll quick(ll a,ll b) {
	ll ans=1,base=a;
	while (b>0) {
		if (b&1) ans*=base;
		base*=base;
		b>>=1;	
	}
	return ans;
}

逆元(包括扩欧)

int exgcd(int a,int b,int &x,int &y) {
	if (b==0) {
		x=1;
		y=0;
		return a;
	}
	int d=exgcd(b,a%b,y,x);
	y-=(a/b)*x;
	return d;
}
int inv(int a,int b) {
	int x,y;
	if (exgcd(a,b,x,y)!=1) return -1;
	else return (x%b+b)%b;
}

线性筛法

for (int i=2;i<=n;i++) {
	if (book[i]) prime[++cnt]=i;
	for (int j=1;j<=cnt&&i*prime[j]<=n;j++) {
		book[i*prime[j]]=0;
		if (i%prime[j]==0) break;
	      }
	}

vector建图

struct Edge {
    int from, to, dist;
    Edge() {}
    Edge(int _from, int _to, int _dist): from(_from), to(_to), dist(_dist) {}
};
vector<Edge> g[MAXN];
for (vector<Edge>::iterator it = g[now].begin(); it != g[now].end(); it++) {
    printf("%d\n", it->to);
}

链式前向星建树

inline void add (int _u,int _v) {
	head[++cnt]=_v;
	Next[cnt]=fat[_u];
	fat[_u]=cnt;
}
//head 子树节点 fat 父亲节点 Next :D

倍增LCA

void dfs(int u) {
      for (int x=fat[u];x;x=Next[x]) {
            if (v[x]==f[0][u]) continue;
            	d[v[x]]=d[u]+1;
		f[0][v[x]]=u;
		dfs(v[x]);
	}
}
void build() {
      for (int i=1;i<=19;i++) 
            for (int j=1;j<=n;j++)
                  f[i][j]=f[i-1][f[i-1][j]];
}
inline int query(int x,int y) {
	if (d[x]>d[y])swap(x,y);
	int delta=d[y]-d[x];
	for (int i=18;i>=0;i--) 
		if (delta>=(1<<i)) y=f[i][y],delta-=(1<<i);
	if (x==y)return x;
	for (int i=19;i>=0;i--)
		if (f[i][x]!=f[i][y])
			x=f[i][x],y=f[i][y];
	return f[0][x];
}

树剖LCA

void dfs1(int u) {
	siz[u]=1;
	for (int x=head[u];x;x=nex[x] ) {
		int v=ver[x];
		if(v!=fa[u]) {
			dep[v]=dep[u]+1;
			fa[v]=u;
			dfs1(v);
			siz[u]+=siz[v];
			if (siz[v]>siz[son[u]]) son[u]=v;
		}
	}
}

void dfs2(int u,int t) {
	id[u]=++tot;
	cur[tot]=a[u];
	top[u]=t;
	if (son[u]) dfs2(son[u],t);
	for (int x=head[u];x;x=nex[x]) {
		int v=ver[x];
		if (v!=fa[u]&&v!=son[u]) dfs2(v,v);
	}
}

inline int LCA(int a,int b) {
	
	while (top[a]!=top[b]) {
		if (dep[top[a]]<dep[top[b]]) swap(a,b);
		a=fa[top[a]];
	}
	if (dep[a]>dep[b]) return b;
	else return a;
}

并查集-路径压缩

int getf(int x) {
	if (f[x]=x) return x;
	return f[x]=getf(f[x]);
}
inline void merge(int a,int b) {
	int t1=getf(a),t2=getf(b);
	if (t1!=t2) f[t1]=t2;
}

优先队列优化--Dijstra

struct note {
	int to,nex,dis;
}edge[M];
inline void add(int a,int b,int d) {
	edge[++cnt].nex=head[a];
	edge[cnt].dis=d;
	edge[cnt].to=b;
	head[a]=cnt;
}
typedef pair<int,int> node;
priority_queue<node,vector<node>,greater<node> >q;
void dij() {
	for (int i=1;i<=n;i++) 
		if (i!=s) {
			dis[i]=inf;
			q.push(node(dis[i],i));
		}
	q.push(node(dis[s]=0,s));
	while(!q.empty()) {
		int minn=q.top().first,mi=q.top().second;
		q.pop();

		if (vis[mi]) continue;
		vis[mi]=1;
		
		for (int i=head[mi];i;i=edge[i].nex) {
			int e=edge[i].to;
			if (minn+edge[i].dis<dis[e]){
				dis[e]=minn+edge[i].dis;
				q.push(node(dis[e],e));
			}
		}
	}
}

最小生成树--Kruskal

struct note {
	int u,v,d;
}edge[M];
inline bool cmp(note a,note b) {return a.d<b.d;}
int getf(int x) {
	if (f[x]==x) return x;
	return f[x]=getf(f[x]);
}
inline bool judge(int a,int b){return getf(a)==getf(b);}
inline void kruskal() {
	sort(edge,edge+n,cmp);
	for (int i=1;i<=m;i++) {
		if (judge(edge[i].u,edge[i].v)) continue;
		ans+=edge[i].d;
		f[edge[i].v]=edge[i].u;
		if (++cnt==n-1) break;
}

背包问题

for (int i=1;i<=n;i++) 
	for (int j=v;j>=w[i];j--) 
		f[j]=max(f[j],f[j-w[i]]+val[i]);
//01背包
for (int i=0;i<=n;i++)
	for (int j=w[i];j<=v;j++) 
		f[j]=max(f[j],f[j-w[i]]+val[i]);
//无限背包
void pre() {
      for (int i=1;i<=n;i++) {
          int x=1;
          while (pi[i]) {
                t[++top]=ti[i]*x;
                p[top]=ci[i]*x;
                pi[i]-=x;
                x*=2;
                if (pi[i]<=x) {
                      t[++top]=ti[i]*pi[i];
                      p[top]=ci[i]*pi[i];
                      break;
                } 
          }
    }
}

缩点 Tarjan

void tarjan(int u) {
	dfn[u]=low[u]=++num;
	st[++top]=u;
	for (int i=head[u];i;i=edge[i].nex) {
		int v=edge[i].to;
		if (!dfn[v]) { //! ?
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else {
			if (!co[v]) 
				low[u]=min(low[u],dfn[v]);
		}
	}
		if (low[u]==dfn[u]) {
			co[u]=++col;
			sii[col]++;
			while(st[top]!=u) {
				co[st[top]]=col;
				top--;
			}
			top--;	
	}
}

posted on 2020-08-17 14:28  正放的瓶塞  阅读(114)  评论(0编辑  收藏  举报