【学习记录】各种模板

以下是手打的一些模板,后期珂能?会继续更新。

各个模板都用模板题测试过正确性了。

线段树:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
namespace Segtree{
  inline int read(){
      register int a=0,f=1;register char c;
      while((c=getchar())<'0')if(c=='-')f=-1;;
      while(c>='0')a=a*10+(c^48),c=getchar();
      return a*f;
  }
  #define lson (way<<1)
  #define rson (way<<1|1)
  #define mid (l+r)/2
  const int MAXN = 1e5+5;
  long long pos[MAXN],seg[MAXN<<2],lz[MAXN<<2];
  inline void build(int way,int l, int r){
    if (l==r) {seg[way] = pos[l];return;}
    build(lson,l,mid);
    build(rson,mid+1,r);
    seg[way] = seg[lson]+seg[rson];
  }
  inline void push(int way, int l, int r){
    if (lz[way]==0) return;
    seg[way]+=lz[way]*(r-l+1);
    if (l!=r)lz[lson]+=lz[way],lz[rson]+=lz[way];
    lz[way] = 0;
  }
  inline void update(int way, int l, int r, int qlow,int qhigh, int val){
    push(way,l,r);
    if (qlow<=l && r<=qhigh){
      lz[way] += val;
      push(way,l,r);
      return;
    }
    if (l>qhigh || r<qlow) return;
    update(lson,l,mid,qlow,qhigh,val);
    update(rson,mid+1,r,qlow,qhigh,val);
    seg[way] = seg[lson]+seg[rson];
  }
  inline long long query(int way, int l, int r, int qlow,int qhigh){
    push(way,l,r);
    if (qlow<=l && r<=qhigh) return seg[way];
    if (l>qhigh || r<qlow) return 0;
    return query(lson,l,mid,qlow,qhigh)+query(rson,mid+1,r,qlow,qhigh);
  }
  void init();
};

dijkstra:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define pp pair<int,int>
#define f first
#define s second
namespace Dijkstra{
  inline int read(){
      register int a=0,f=1;register char c;
      while((c=getchar())<'0')if(c=='-')f=-1;;
      while(c>='0')a=a*10+(c^48),c=getchar();
      return a*f;
  }
  const int MAXN = 1e5+5;
  const int MAXM = 2e5+5;
  int n,m,k,dist[MAXN],head[MAXN],tot;
  struct Edge{
    int f,t,nxt,dis;
  }edge[MAXM];
  inline void add(int f,int t, int d){
    edge[++tot].f = f;
    edge[tot].t = t;
    edge[tot].dis = d;
    edge[tot].nxt = head[f];
    head[f] = tot;
  }
  inline void dij(int source){
    priority_queue<pp> q;
    memset(dist,0x3f3f,sizeof(dist));
    dist[source] = 0;
    q.push(make_pair(0,source));
    while(!q.empty()){
      int qf = -q.top().f,qs = q.top().s; q.pop();
      if (dist[qs]<qf) continue;
      for (int i=head[qs];i;i=edge[i].nxt){
        int v = edge[i].t,d = edge[i].dis;
        if (dist[v]>dist[qs]+d){
          dist[v] = dist[qs]+d;
          q.push(make_pair(-dist[v],v));
        }
      }
    }
  }
  inline int dijk(int source, int to){
    priority_queue<pp> q;
    memset(dist,0x3f3f,sizeof(dist));
    dist[source] = 0;
    q.push(make_pair(0,source));
    while(!q.empty()){
      int qf = -q.top().f,qs = q.top().s; q.pop();
      if (dist[qs]<qf) continue;
      if (qs==to) return dist[to];
      for (int i=head[qs];i;i=edge[i].nxt){
        int v = edge[i].t,d = edge[i].dis;
        if (dist[v]>dist[qs]+d){
          dist[v] = dist[qs]+d;
          q.push(make_pair(-dist[v],v));
        }
      }
    }
    return 0x3f3f;
  }
  void init();
  void solve();
}

spfa求负环

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define pp pair<int,int>
#define f first
#define s second
namespace Spfa{
  inline int read(){
      register int a=0,f=1;register char c;
      while((c=getchar())<'0')if(c=='-')f=-1;;
      while(c>='0')a=a*10+(c^48),c=getchar();
      return a*f;
  }
  const int MAXN = 1e5+5;
  const int MAXM = 2e5+5;
  int n,m,k,dist[MAXN],head[MAXN],tot,sz[MAXN];
  bool vis[MAXN];
  struct Edge{
    int f,t,nxt,dis;
  }edge[MAXM];
  inline void add(int f,int t, int d){
    edge[++tot].f = f;
    edge[tot].t = t;
    edge[tot].dis = d;
    edge[tot].nxt = head[f];
    head[f] = tot;
  }
  inline bool spfa(int source){
    queue<int> q;
    memset(dist,0x3f3f,sizeof(dist));
    dist[source] = 0;
    q.push(source);
    while(!q.empty()){
      int qf = q.front();q.pop();
      vis[qf] = false;
      for (int i=head[qf];i;i=edge[i].nxt){
        int v = edge[i].t,d = edge[i].dis;
        if (dist[v]>dist[qs]+d){
          dist[v] = dist[qs]+d;
          if (++sz[v]>n) return true;
          if (!vis[v]) vis[v] = true,q.push(v);
        }
      }
    }
    return false;
  }
  void init();
  void solve();
}

tarjan算法

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <vector>
#include <unordered_map>
using namespace std;
namespace Tarjan{
  const int MAXN = 1e5+5;
  const int MAXM = 2e5+5;
  int n,m,cnt,tot,in[MAXN],head[MAXN],dfn[MAXN],maxi[MAXN],low[MAXN],val[MAXN],curr,stt,scc[MAXN],num[MAXN],dp[MAXN],ans,a,b;
  bool vis[MAXN];
  vector<int> nums[MAXN];
  stack<int> st;
  struct Edge{
    int f,t,nxt;
  }edge[MAXM];
  inline void add(int f,int t){
    edge[++tot].f = f;
    edge[tot].t = t;
    edge[tot].nxt = head[f];
    head[f] = tot;
  }
  inline void tarjan(int pos){
    st.push(pos);
    dfn[pos]=low[pos] = ++cnt;
    vis[pos] = true;
    for (int i=head[pos];i;i=edge[i].nxt){
      int v = edge[i].t;
      if (!dfn[v]){
        tarjan(v);
        low[pos] = min(low[pos],low[v]);
      }else if (vis[v]) low[pos] = min(low[pos],dfn[v]);
    }
    if (low[pos]==dfn[pos]){
      curr++;
      do{
        stt = st.top();
        st.pop();
        vis[stt] = false;
        scc[stt] = curr;
        nums[curr].push_back(stt);
        val[curr]+=num[stt];
      }while(stt!=pos);
    }
  }
  inline void tarj(){
    for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
  }
  inline void dfs(int pos){
    vis[pos] = true;
    dp[pos] = val[pos];
    int addi = 0;
    for (int i : nums[pos]){
      for (int j=head[i];j;j=edge[j].nxt){
        int v = scc[edge[j].t];
        if(v==pos) continue;
        if (!vis[v]) dfs(v);
        addi = max(addi,dp[v]);
      }
    }

    dp[pos]+=addi;
    ans = max(ans,dp[pos]);
  }
  inline void topo(){
    queue<int> q;
    unordered_map<int,unordered_map<int,bool> > mp,mp2;
    for (int i=1;i<=curr;i++){
      for (int j : nums[i]){
        for (int k=head[j];k;k=edge[k].nxt){
          int v = scc[edge[k].t];
          if (v==i || mp[i][v]) continue;
          mp[i][v] = true;
          in[v]++;
        }
      }
    }
    swap(mp,mp2);
    for(int i=1;i<=curr;i++) {
      ans = max(ans,val[i]);
      if (!in[i]) q.push(i);
    }
    while(!q.empty()){
      int qf = q.front(); q.pop();
      dp[qf]+=val[qf]+maxi[qf];
      ans = max(ans,dp[qf]);
      for (int i : nums[qf]){
        for (int j=head[i];j;j=edge[j].nxt){
          int v = scc[edge[j].t];
          if (v==qf) continue;
          if (!mp[qf][v] && in[v]){
            mp[qf][v] = true;
            maxi[v] = max(maxi[v],dp[qf]);
            if ((--in[v])==0) q.push(v);
          }
        }
      }
    }
  }
  inline void init();
  inline void solve();
}

割点:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <vector>
#include <unordered_map>
using namespace std;
namespace Articulation{
  inline int read(){
      register int a=0,f=1;register char c;
      while((c=getchar())<'0')if(c=='-')f=-1;;
      while(c>='0')a=a*10+(c^48),c=getchar();
      return a*f;
  }
  const int MAXN = 1e5+5;
  const int MAXM = 2e5+5;
  int n,m,cnt,tot,in[MAXN],rt,head[MAXN],dfn[MAXN],low[MAXN],curr,stt,ans,a,b;
  bool vis[MAXN],cut[MAXN];
  stack<int> st;
  struct Edge{
    int f,t,nxt;
  }edge[MAXM];
  inline void add(int f,int t){
    edge[++tot].f = f;
    edge[tot].t = t;
    edge[tot].nxt = head[f];
    head[f] = tot;
  }
  inline void tarjan(int pos, int fa){
    int child = 0;
    st.push(pos);
    dfn[pos]=low[pos] = ++cnt;
    vis[pos] = true;
    for (int i=head[pos];i;i=edge[i].nxt){
      int v = edge[i].t;
      if (v==fa) continue;
      if (!dfn[v]){
        tarjan(v,pos);
        child++;
        low[pos] = min(low[pos],low[v]);
        if (!cut[pos] && ((rt==pos && child>=2) || (rt!=pos && low[v] >= dfn[pos]))) cut[pos] = true;
      }else low[pos] = min(low[pos],dfn[v]);
    }
  }
  inline void tarj(){
    for (int i=1;i<=n;i++) if (!dfn[i]) rt=i,tarjan(i,i);
  }
  inline int num_of_points(){
    int re = 0;
    for (int i=1;i<=n;i++) if (cut[i]) re++;
    return re;
  }
  inline void init();
  inline void solve();
}

Kruskal:

#include <iostream>
#include <algorithm>
using namespace std;
namespace Kruskal{
  const int MAXN = 1e5+5;
  const int MAXM = 1e5+5;
  int n,m,k,a,b,c,fa[MAXN],tot;
  struct Edge{
    int f,t,dis;
    bool operator < (const Edge &oth) const{
      return dis<oth.dis;
    }
  }edge[MAXM];
  inline void add(int f, int t, int d){
    edge[++tot].f = f;
    edge[tot].t = t;
    edge[tot].dis = d;
  }
  inline int Find(int x){
    while(x!=fa[fa[x]]) x = fa[x] = Find(fa[fa[x]]);
    return x;
  }
  inline void Union(int x, int y){
    fa[Find(x)] = Find(y);
  }
  inline int connect(){
    for(int i=1;i<=n;i++) fa[i] = i;
    int re = 0;
    sort(edge+1,edge+1+tot);
    for (int i=1;i<=tot;i++){
      if (k==n-1) break;
      int f = edge[i].f, t = edge[i].t, d = edge[i].dis;
      if(Find(f)!=Find(t)) {re+= d; Union(f,t);k++;}
    }
    return re;
  }
  inline void init();
  inline void solve();
}

扫描线:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <vector>
using namespace std;
const int MAXN = 4e5+5;
#define lson (way<<1)
#define rson (way<<1|1)
#define mid (l+r)/2

namespace SweepLine{
  long long x_pos[MAXN<<2],tot;
  long long a,b,c,d,cnt,ans,n;
  long long pos[MAXN];
  namespace Segtree{
    inline int read(){
        register int a=0,f=1;register char c;
        while((c=getchar())<'0')if(c=='-')f=-1;;
        while(c>='0')a=a*10+(c^48),c=getchar();
        return a*f;
    }
    struct SegTree{
      long long l,r,val,len,lz;
    }seg[MAXN<<2];
    inline void build(int way,int l, int r){
      seg[way].l = l;seg[way].r = r;
      seg[way].val = seg[way].len = 0;
      if (l==r) return;
      build(lson,l,mid);
      build(rson,mid+1,r);
    }
    inline void push(int way){
      int l = seg[way].l, r = seg[way].r;
      if(seg[way].val) {
        seg[way].len = x_pos[r+1]-x_pos[l];
      }else if (l!=r){
        seg[way].len = seg[lson].len + seg[rson].len;
      }else seg[way].len=0;
    }
    inline void update(int way, int l, int r, int qlow,int qhigh, int val){
      if (qlow<=l && r<=qhigh){
        seg[way].val += val;
        push(way);
        return;
      }
      if (l>qhigh || r<qlow || l==r) return;
      update(lson,l,mid,qlow,qhigh,val);
      update(rson,mid+1,r,qlow,qhigh,val);
      push(way);
    }
  };
  struct Edge{
    int x1,x2,y,val;
    bool operator <(const Edge& oth) const{
      return y<oth.y || (y==oth.y && val>oth.val);
    }
  }edge[MAXN<<2];
  inline void add(int x1,int x2, int y, int val){
    edge[++tot].x1 = x1;
    edge[tot].x2 = x2;
    edge[tot].y = y;
    edge[tot].val = val;
  }
  inline int Find(int num){
    int l = 1, r = cnt;
    while(l!=r){
      if (x_pos[mid]==num) return mid;
      if (x_pos[mid]>num) r = mid-1;
      else l = mid+1;
    }
    return l;
  }
  inline void Find_area(){
    sort(edge+1,edge+1+tot);
    sort(x_pos+1,x_pos+1+tot);
    cnt = unique(x_pos+1,x_pos+tot+1)-x_pos-1;
    for (int i=1;i<tot;i++){
      int x1 = Find(edge[i].x1),x2 = Find(edge[i].x2),val = edge[i].val;
      Segtree::update(1,1,tot,x1,x2-1,val);
      ans+=Segtree::seg[1].len*abs(edge[i+1].y-edge[i].y);
    }
  }
  inline void init();
  inline void solve();
}
原文地址:https://www.cnblogs.com/DannyXu/p/12934779.html