【学习记录】各种模板
以下是手打的一些模板,后期珂能?会继续更新。
各个模板都用模板题测试过正确性了。
线段树:
#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();
}