模板大集合 - Part 2

网络流

Dinic

#include <某.h>
using namespace Atomic::fastSTD;
using namespace AllRangeApply_Define;

namespace my{

const int M = 200005,N = 10005; 

int head[N],to[M],nxt[M],val[M],cnt = 1;

void addedge(int u,int v,int w){
	nxt[++cnt] = head[u];
	to[cnt] = v;
	val[cnt] = w;
	head[u] = cnt;
}

int cur[N],d[N];
int s,t;

bool bfs() {
	memset(d,0,sizeof(d));
	queue<int> q;
	q.push(s);
	d[s] = 1;
	while(q.size()){
		int u = q.front();
		q.pop();
		for(int i = head[u];i;i = nxt[i]) {
			int v = to[i];
			if(d[v] == 0 && val[i]) {
				d[v] = d[u] + 1;
				q.push(v);
				if(v == t) return true;
			} 
		}
	}
	return false;
}

int dfs(int u,int mf) {
	if(u == t) return mf;
	int sum = 0;
	for(int i = cur[u];i;i = nxt[i]) {
		cur[u] = i;
		int v = to[i];
		if(d[v]==d[u] + 1 && val[i]) {
			int f = dfs(v,min(mf,val[i]));
			val[i] -= f;
			val[i ^ 1] += f;
			sum += f;
			mf -= f;
			if(mf == 0) break;
		}
	}
	if(!sum) d[u] = 0;
	return sum;
}

int n,m;

signed main() {

	n = read(),m = read();
	s = read(),t = read();

	for(int i = 1;i<=m;i++) {
		int u,v,w;
		u = read(),v = read(),w = read();
		addedge(u,v,w);
		addedge(v,u,0);
	}

	int flow = 0;
	while(bfs()) {
		memcpy(cur,head,sizeof(head));
		flow += dfs(s,1e9);
	}

	write(flow);
	
	return 0;
}

}

signed main() {
	return my::main();
}

HLPP(预流推进)

#include <bits/stdc++.h>
using namespace std;
//省略头...
namespace my{

const int N = 2405,M = 240005,INF = 0x3f3f3f3f3f3f3f3f;

int nxt[M<<1],to[M<<1],val[M<<1],head[N],cnt = 1;

void addedge(int u,int v,int w) {
	nxt[++cnt] = head[u];
	to[cnt] = v;
	val[cnt] = w;
	head[u] = cnt;
}

int h[N];
int ex[N],gap[N];
stack<int> B[N];
int level = 0;
int n,m,s,t;

int push(int u) {
	bool init = u == s;
	for(int i = head[u];i;i = nxt[i]) {
		const int &v = to[i];
		const int &w = val[i];
		if(!w || (init == false && h[u] != h[v] + 1) || h[v] == INF) continue;
		int k = init ? w :min(w,ex[u]);
		if(v != s && v != t && !ex[v]) B[h[v]].push(v),level = max(level,h[v]);
		ex[u] -= k,ex[v] += k,val[i] -= k,val[i ^ 1] += k;
		if(!ex[u]) return 0;
	}
	return 1;
}

void relab(int u) {
	h[u] = INF;
	for(int i = head[u];i;i = nxt[i]) if(val[i]) h[u] = min(h[u],h[to[i]]);
	if(++h[u] < n) {
		B[h[u]].push(u);
		level = max(level,h[u]);
		++gap[h[u]];
	}
}

bool bfs() {
	memset(h,0x3f,sizeof(h));
	queue<int> q;
	q.push(t);
	h[t] = 0;
	while(q.size()) {
		int u = q.front();
		q.pop();
		for(int i = head[u];i;i = nxt[i]) {
			const int &v = to[i];
			if(val[i ^ 1] && h[v] > h[u] + 1) h[v] = h[u] + 1,q.push(v);
		}
	}
	return h[s] != INF;
}

int select() {
	while(level > -1 && B[level].size() == 0) level--;
	return level == -1 ? 0 : B[level].top();
}

int hlpp() {
	if(!bfs()) return 0;
	memset(gap,0,sizeof(gap));
	for(int i = 1;i<=n;i++) if(h[i] ^ INF) gap[h[i]]++;
	h[s] = n;
	push(s);
	int u;
	while((u = select())) {
		B[level].pop();
		if(push(u)) {
			if(!--gap[h[u]]) 
				for(int i = 1;i<=n;i++) 
					if(i ^ s && h[i] > h[u] && h[i] < n + 1) 
						h[i] = n + 1;
			relab(u);
		}
	}
	return ex[t];
}


signed main() {
	n = read(),m = read(),s = read(),t = read();

	for(int i = 1;i<=m;i++) {
		int u,v,c;
		u = read(),v = read(),c = read();
		addedge(u,v,c);
		addedge(v,u,0);
	}
	write(hlpp());

	return 0;
}

}

signed main() {
	return my::main();
}

李超线段树(【模板】李超线段树 / [HEOI2013] Segment)

#include <bits/stdc++.h>
using namespace std;


#define MJY(p) freopen(p".in","r",stdin);freopen(p".out","w",stdout);
#define pdi pair<double,int>
#define fir first
#define sec second

const int mod1 = 39989,mod2 = 1e9;
int n,op,lastans = 0;
const double eps = 1e-9;

int cmp(double x,double y) {
	if(x - y > eps) return 1;
	if(y - x  > eps) return -1;
	return 0;
}

struct line{
	double k,b;
}p[100005];

int s[160005],cnt;
double calc(int id,int d) {
	return p[id].b + p[id].k * d;
}

void add(int x0,int y0,int x1,int y1) {
	cnt++;
	if(x0 == x1) p[cnt].k = 0,p[cnt].b = max(y0,y1);
	else p[cnt].k = 1.0 * (y1 - y0)/(x1  - x0),p[cnt].b = y0 - p[cnt].k * x0;
}

void upd(int root,int cl,int cr,int u) {
	int &v = s[root],mid = (cl + cr) >> 1;
	int bmid = cmp(calc(u,mid),calc(v,mid));
	if(bmid == 1 || (!bmid && u < v)) swap(u,v);
	int bl = cmp(calc(u,cl),calc(v,cl)),br = cmp(calc(u,cr),calc(v,cr));
	if(bl == 1 || (!bl && u < v)) upd(root<<1,cl,mid,u);
	if(br == 1 || (!br && u<v)) upd(root<<1|1,mid+1,cr,u);
}

void update(int root,int cl,int cr,int l,int r,int u) {
	if(l <= cl && cr <= r) {
		upd(root,cl,cr,u);
		return;
	}
	int mid = (cl + cr) >> 1;
	if(l <= mid) update(root<<1,cl,mid,l,r,u);
	if(mid < r) update(root<<1|1,mid+1,cr,l,r,u);
}

pdi pmax(pdi x,pdi y) {
	if(cmp(x.fir,y.fir) == -1) return y;
	else if(cmp(x.fir,y.fir) == 1) return x;
	else return x.sec < y.sec ? x : y;
}

pdi query(int root,int l,int r,int d) {
	if(r < d || d < l) return {0,0};
	int mid = (l + r) >> 1;
	double res = calc(s[root],d);
	if(l == r) return {res,s[root]};
	return pmax({res,s[root]},pmax(query(root<<1,l,mid,d),query(root<<1|1,mid+1,r,d)));
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	
	cin>>n;
	for(int i = 1;i<=n;i++) {
		cin>>op;
		if(op) {
			int x0,y0,x1,y1;
			cin>>x0>>y0>>x1>>y1;
			x0 = (x0 + lastans - 1 + mod1) % mod1 + 1;
			x1 = (x1 + lastans -1 + mod1) % mod1 + 1;
			y0 = (y0 + lastans - 1 + mod2) % mod2 + 1;
			y1 = (y1 + lastans -1 + mod2) % mod2 + 1;
			if(x0 > x1) swap(x0,x1),swap(y0,y1);
			add(x0,y0,x1,y1);
			update(1,1,mod1,x0,x1,cnt);
		}else {
			int k;
			cin>>k;
			k = (k + lastans-1 + mod1) % mod1 + 1;
			cout<<(lastans = query(1,1,mod1,k).second)<<'\n';
		}
	}
	
	
	return 0;
}

[树剖 + 李超树]GAME

#define useLL
#include <bits/stdc++.h>
using namespace std;

// 省略头....

namespace my{

const int N = 100005,inf = 123456789123456789LL;

int nxt[N<<1],to[N<<1],head[N],val[N<<1],cnt;

int lcnt = 0;

void init(){
	memset(head,-1,sizeof(head));
	cnt = 0;
}

void addedge(int u,int v,int w) {
	nxt[cnt] = head[u];
	to[cnt] = v;
	val[cnt] = w;
	head[u] = cnt++;
}

int n,m;

int fa[N],size[N],dep[N],son[N],top[N],dis[N],dfn[N],old[N];

void dfs1(int x,int f){
	fa[x] = f;
	dep[x] = dep[f] + 1;
	size[x] = 1;
	for(int i = head[x];~i;i = nxt[i]) {
		int y = to[i];
		if(y ^ f) {
			dis[y] = dis[x] + val[i];
			dfs1(y,x);
			size[x] += size[y];
			if(size[son[x]] < size[y]) son[x] = y;
		}
	}
}
int num;
void dfs2(int x,int topx) {
	top[x] = topx;
    dfn[x] = ++num;
    old[num] = x;
	if(!son[x]) return;
	dfs2(son[x],topx);
	for(int i = head[x];~i; i = nxt[i]) {
		int y = to[i];
		if(y ^ son[x] && y ^ fa[x]) dfs2(y,y);
	}
}

int lca(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]) swap(x,y);
	return x;
}

struct line{
	int k,b;
	line(){k = 0,b = inf;}
	line(int k,int b) :k(k),b(b){}
}ln[N<<1];

namespace sgt{
#define ls (p << 1)
#define rs (p << 1 | 1)
#define mid ((pl + pr) >> 1)

struct node{
	int id;
	int mi;
	node(){mi = inf;}
}t[N<<3];

int y(int id,int x){
	return ln[id].k * x + ln[id].b;
}

#define id(x) t[(x)].id
#define mi(x) t[(x)].mi

void push_up(int p,int pl,int pr) {
	int ans = min(y(id(p),dis[old[pl]]),y(id(p),dis[old[pr]]));
    mi(p) = min(ans,min(mi(ls),mi(rs)));
}

void update(int p,int pl,int pr,int l,int r,int id){ //??
  if(l <= pl && pr <= r){
    if(y(id,dis[old[mid]])<y(t[p].id,dis[old[mid]])) swap(id,t[p].id);
    if(y(id,dis[old[pl]])<y(t[p].id,dis[old[pl]])) update(ls,pl,mid,l,r,id);
    if(y(id,dis[old[pr]])<y(t[p].id,dis[old[pr]])) update(rs,mid+1,pr,l,r,id);
    push_up(p,pl,pr);
    return;
  }
  if(l<=mid) update(ls,pl,mid,l,r,id);
  if(r>mid) update(rs,mid+1,pr,l,r,id);
  push_up(p,pl,pr);
}


int query(int p,int pl,int pr,int l,int r) {
    if(l <= pl && pr <= r) return mi(p);
    int ans = min(y(id(p),dis[old[max(pl,l)]]),y(id(p),dis[old[min(pr,r)]]));
    if(l <= mid) ans = min(ans,query(ls,pl,mid,l,r));
    if(r > mid) ans = min(ans,query(rs,mid+1,pr,l,r));
    return ans;
}

}

void update(int x,int y,int id){
    while(top[x] ^ top[y]) {
        if(dep[top[x]] < dep[top[y]]) swap(x,y);
        sgt::update(1,1,n,dfn[top[x]],dfn[x],id);
        x = fa[top[x]];
    }
    if(dep[x] > dep[y]) swap(x,y);
    sgt::update(1,1,n,dfn[x],dfn[y],id);
}

int query(int x,int y) {
    int ans = inf;
    while(top[x] ^ top[y]) {
        if(dep[top[x]] < dep[top[y]]) swap(x,y);
        ans = min(ans,sgt::query(1,1,n,dfn[top[x]],dfn[x]));
        x = fa[top[x]];
    }
    if(dep[x] > dep[y]) swap(x,y);
    return min(ans,sgt::query(1,1,n,dfn[x],dfn[y]));
}

signed main() {
    init();
	n = read(),m = read();

	for(int i = 1,u,v,w;i<n;i++) {
		u = read(),v = read(),w = read();
		addedge(u,v,w);
		addedge(v,u,w);
	} 
	dfs1(1,0);
	dfs2(1,1);

	int opt,a,b,l,s,t;
	while(m--) {
		opt = read(),s = read(),t = read();
		if(opt == 1){
            a = read(),b = read();
			l = lca(s,t);
			ln[++lcnt] = line(-a,a * dis[s] + b);
			update(s,l,lcnt);
			ln[++lcnt] = line(a,a * (dis[s] - 2 * dis[l]) + b);
			update(l,t,lcnt);
		}else {
			write(query(s,t));
            puts("");
		}
	}
	
	return 0;
}

}

signed main() {
	return my::main();
}

李超优化 d p dp dp ([CEOI2017] Building Bridges)

#include <bits/stdc++.h>
using namespace std;


#define MJY(p) freopen(p".in","r",stdin);freopen(p".out","w",stdout);
#define int long long
#define ls (k<<1)
#define rs (k<<1|1)

const int N = 2e5+9,M = 2e6+9;
int a[N],b[N],h[N],w[N],f[N];
int s[M<<2],u;

int g(int x,int o) {
	return b[o] + a[o] * x;
}

void upd(int k,int l,int r,int t) {
	if(l == r) {
		if(g(l,r) < g(l,s[k])) s[k] = t;
		return;
	}
	int mid = (l + r) >> 1;
	if(g(mid,t) < g(mid,s[k])) swap(t,s[k]);
	if(g(l,t) < g(l,s[k])) upd(ls,l,mid,t);
	else if(g(r,t) < g(r,s[k])) upd(rs,mid+1,r,t);
}

int query(int k,int l,int r) {
	if(l == r) return g(u,s[k]);
	int mid = (l + r) >>1;
	return min(g(u,s[k]),u <= mid ? query(ls,l,mid) : query(rs,mid+1,r));
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	
	int n;
	cin>>n;
	b[0] = 1e18;
	for(int i = 1;i<=n;i++) cin>>h[i];
	for(int i = 1;i<=n;i++) cin>>w[i];
	for(int i = 1;i<=n;i++) w[i] += w[i-1];
	a[1] = -2 * h[1],b[1] = h[1] * h[1] - w[1],upd(1,0,M,1);
	for(int i = 2;i<=n;i++) {
		u = h[i],f[i] = h[i] * h[i] + w[i-1] + query(1,0,M);
		a[i] = -2 * h[i],b[i] = f[i] + h[i] * h[i] - w[i],upd(1,0,M,i);
	}
	
	cout<<f[n];
	
	return 0;
}

树套树(线段树套线段树)[HDU1823]

#include <bits/stdc++.h>
using namespace std;
// 省略头...
namespace my{
using namespace AllRangeApply_Define;
using namespace Atomic::normalSTD;
//using namespace Atomic::fastSTD;
//using namespace Atomic::SuperSTD;

namespace sgm{

#define ls (p << 1)
#define rs (ls | 1)
#define mid ((pl + pr) >> 1)
int n = 1e3,s[1005][4005];//s -- 身高区间 i & 活泼区间 j -> xp_max

//--------------------------------------------------------------------------------
namespace subSgm{

void subbuild(int p,int pl,int pr,int xp) {
	s[xp][p] = -1;
	if(pl == pr) return;
	subbuild(ls,pl,mid,xp);
	subbuild(rs,mid+1,pr,xp);
}

void subupdate(int p,int pl,int pr,int xp,int y,int c){
	if(pl == pr && pl == y) s[xp][p] = max(s[xp][p],c);
	else{
		if(y <= mid) subupdate(ls,pl,mid,xp,y,c);
		else subupdate(rs,mid+1,pr,xp,y,c);
		s[xp][p] = max(s[xp][ls],s[xp][rs]);
	}
}

int subquery(int p,int pl,int pr,int xp,int l,int r) {
	if(l <= pl && pr <= r) return s[xp][p];
	else {
		int res = -1;
		if(l <= mid) res = max(res,subquery(ls,pl,mid,xp,l,r));
		if(r > mid) res = max(res,subquery(rs,mid+1,pr,xp,l,r));
		return res;
	}
}

}
//------------------------------------------------------------------------------------
namespace mainSgm{

void build(int p,int pl,int pr) {
	subSgm::subbuild(1,0,n,p);
	if(pl == pr) return;
	build(ls,pl,mid);
	build(rs,mid+1,pr);
}

void update(int p,int pl,int pr,int x,int y,int c){
	subSgm::subupdate(1,0,n,p,y,c);
	if(pl ^ pr) {
		if(x <= mid) update(ls,pl,mid,x,y,c);
		else update(rs,mid+1,pr,x,y,c);
	}
}

int query(int p,int pl,int pr,int xl,int xr,int yl,int yr){
	if(xl <= pl && pr <= xr) return subSgm::subquery(1,0,n,p,yl,yr);
	else {
		int res = -1;
		if(xl <= mid) res = max(res,query(ls,pl,mid,xl,xr,yl,yr));
		if(xr > mid) res = max(res,query(rs,mid+1,pr,xl,xr,yl,yr));
		return res;
	}
}

}
//-----------------------------------------------------------------------------------------
}


signed main(){
	speed_up(false);
	int t;
	while(scanf("%lld",&t)){
		if(!t) return 0;
		sgm::mainSgm::build(1,100,200);
		while(t--) {
			char opt;
			int h,hl,hr,ans;
			double a,l;
			opt = getchar();
			while(opt == ' ' || opt == '\n') opt = getchar();
			switch(opt){
				case 'I':
					scanf("%lld%lf%lf",&h,&a,&l);
					sgm::mainSgm::update(1,100,200,h,a * 10,l * 10);
					break;
				case 'Q':
					scanf("%lld%lld%lf%lf",&hl,&hr,&a,&l);
					if(hl > hr) swap(hl,hr);
					if(a > l) swap(a,l);
					ans = sgm::mainSgm::query(1,100,200,hl,hr,a*10,l*10);
					if(ans == -1) printf("%d",-1);
					else printf("%.1lf\n",(ans * 1.0)/10.0);
			}
		}
	}
	return 0;
}

}
signed main() {
	return my::main();
}

kmp

#include <bits/stdc++.h>
using namespace std;
#define N 200005

string a,b;
int nxt[N];

void getnxt(string s) {
	int j = -1;
	nxt[0] = j;
	for(int i = 1;i<s.size();i++) {
		while(j>=0&&s[i] != s[j+1]) j = nxt[j];
		if(s[i] == s[j+1]) j++;
		nxt[i] = j;
	}
}


int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	
	cin>>a>>b;
	
	getnxt(b);
	
	int j = -1;
	for(int i = 0;i<a.size();i++) {
		while(j>=0&&a[i] != b[j+1]) j = nxt[j];
		if(a[i] == b[j+1]) j++;
		if(j == b.size()-1) {
			cout<<i - b.size() + 2<<'\n';
			j = nxt[j];
		} 
	}
	
	for(int i = 0;i<b.size();i++) cout<<nxt[i]+1<<' ';
	
	
	return 0;
}

AC自动机

#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 5;

int ch[N][26],nxt[N],cnt[N],idx;

void insert(char *s) {
	int p = 0;
	for(int i = 0;s[i];i++) {
		int j = s[i] - 'a';
		if(!ch[p][j]) ch[p][j] = ++idx;
		p = ch[p][j];
	}
	cnt[p]++;
}

void build() {
	queue<int> q;
	for(int i = 0;i<26;i++) 
		if(ch[0][i]) q.push(ch[0][i]);
	while(!q.empty()) {
		int u = q.front();
		q.pop();
		for(int i = 0;i<26;i++) {
			int v = ch[u][i];
			if(v) nxt[v] = ch[nxt[u]][i],q.push(v);
			else ch[u][i] = ch[nxt[u]][i];
		}
	}
}

int query(char *s) {
	int ans = 0;
	for(int k = 0,i = 0;s[k];k++) {
		i = ch[i][s[k] - 'a'];
		for(int j = i;j && ~cnt[j];j = nxt[j])
			ans += cnt[j],cnt[j] = -1;
	}
	return ans;
}

int n;
char s[N],t[N];

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	
	cin>>n;
	for(int i = 1;i<=n;i++) {
		cin>>s;
		insert(s);
	}
	cin>>t;
	build();
	cout<<query(t);

	return 0;
}

tarjan缩点

const int N = 1e4+5;
int low[N],num[N],dfn,co[N],col,st[N],top,sum[N];

void tarjan(int u) {
	low[u] = num[u] = ++dfn;
	st[++top] = u;
	for(int v:g[u]) {
		if(!num[v]) {
			tarjan(v);
			low[u] = min(low[u],low[v]);
		}else if(!co[v]) low[u] = min(low[u],num[v]);
	}
	if(num[u] == low[u]) {
		co[u] = ++col;
		sum[col] += a[u];
		while(st[top] != u) {
			sum[col] += a[st[top]];
			co[st[top]] = col;
			--top;
		}
		--top;
	}
}

for(int i = 1;i<=n;i++) if(!num[i]) tarjan(i);	

矩阵快速幂

struct matrix {
    int M[40][40];
    matrix() { memset(M, 0, sizeof(M)); }
    matrix(bool flag) {for (int i = 0; i < (1 << m); i++) M[i][i] = 1;}
    int* operator[](const int pos) { return M[pos]; }
    friend matrix operator*(matrix a, matrix b) {
        matrix c;
        for (int i = 0; i < (1 << m); i++)
            for (int j = 0; j < (1 << m); j++)
                for (int K = 0; K < (1 << m); K++)
                     c[i][j] = c[i][j] + a[i][K] * b[K][j];
        return c;
    }
};

matrix qpow(matrix a,int k) {
	matrix res(true);
	while(k) {
		if(k & 1) res = (res * a);
		a = (a * a);
		k >>= 1;
	}
	return res;
}

Johnson

#include <bits/stdc++.h>
using namespace std;



#define int long long
#define ll long long

const int N = 3005;
const int INF = 1e9;
const int M = 6005;

struct Edge{
	int to,val;
	Edge(int t,int v) :to(t),val(v) {}
	inline  bool operator < (const Edge &a) const {
		return a.val < val;
	}
};

vector<Edge> edge[N];
int n,m,u,v,w;
ll h[N],dis[N];
int Neg[N];
bool inq[N],vis[N];

inline  bool spfa(){
	deque<int> dq;
	h[0] = 0;
	Neg[0] = 1;
	inq[0] = true;
	dq.push_back(0);
	while(!dq.empty()){
		int t = dq.front();
		dq.pop_front();
		inq[t] = false;
		for(Edge a:edge[t]) {
			if(h[a.to] > h[t] + a.val) {
				h[a.to] = h[t] + a.val;
				if(!inq[a.to]){
					inq[a.to] = true;
					dq.push_back(a.to);
					// ??????SLF 
					Neg[a.to]++;
					if(Neg[a.to] == n+1) return true;
				}
			}
		}
	}
	return false;
}

inline  void dij(int s) {
	For(u,0,n) vis[u] = false,dis[u] = INF;
	priority_queue<Edge> q;
	q.push(Edge(s,0));
	dis[s] = 0;
	while(!q.empty()) {
		Edge t = q.top();
		q.pop();
		if(vis[t.to]) continue;
		vis[t.to] = true;
		for(Edge a:edge[t.to]) {
			if(vis[a.to]) continue;
			if(dis[a.to] > dis[t.to] + a.val) {
				dis[a.to] = dis[t.to] + a.val;
				q.push(Edge(a.to,dis[a.to]));
			}
		}
	}
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	
	cin>>n>>m;
	For(u,0,n) h[u] = INF,dis[u] = INF;
	
	for(int i = 1;i<=m;i++){
		cin>>u>>v>>w;
		edge[u].push_back(Edge(v,w));
	}
	
	for(int i = 1;i<=n;i++) edge[0].push_back(Edge(i,0));
	
	if(spfa()) cout<<-1,exit(0);
	for(int i = 1;i<=n;i++){
		for(Edge &a:edge[i]) {
			// copy ????? important 
			a.val += h[i] - h[a.to];
		}
	}
	
	for(int i = 1;i<=n;i++) {
		ll ans = 0;
		dij(i);
		For(j,1,n) {
			if(dis[j] == INF){
				ans += j*INF;
			}else ans += j*(dis[j] + h[j] - h[i]);
		}
		cout<<ans<<'\n';
	}
	
	
	return 0;
}

克鲁斯卡尔(kru)

#include <bits/stdc++.h>
using namespace std;
#define For(i,n) for(register int i = 1;i<=n;i++)



const int N = 5005;
const int M = 200005; 

struct Edge{
	int u,v,w;
}edge[M<<1];

int s[N<<1],cnt,n,m,ans;
inline  bool cmp(const Edge &a,const Edge &b) { return a.w < b.w;}

inline  int find(int x){
	if(x != s[x]) s[x] = find(s[x]);
	return s[x];
}

inline  void kru(){
	sort(edge+1,edge+1+m,cmp);
	int f1,f2;
	For(i,n) s[i] = i;
	For(i,m){
		f1 = find(edge[i].u);
		f2 = find(edge[i].v);
		if(f1 != f2) {
			ans += edge[i].w;
			s[f1] = f2;
			cnt++;
			if(cnt == n-1) break;
		}
	}
	if(cnt != n-1) cout<<"orz";
	else cout<<ans;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	cin>>n>>m;
	for(int i = 1;i<=m;i++) cin>>edge[i].u>>edge[i].v>>edge[i].w;
	kru();
	
	
	return 0;
}


Prim

#include <bits/stdc++.h>
using namespace std;
#define For(i,n) for(register int i = 1;i<=n;i++)



const int N = 5005;
const int M = 200005;

struct node{
	int to,val;
	node(int t,int v) : to(t),val(v){}
	inline  bool operator < (const node &a) const{
		return a.val < val;
	}
};

int n,m,cnt,now = 1;
bool vis[N];
vector<node> edge[N];

inline  void prim(){
	int ans = 0;
	priority_queue<node> q;
	q.push(node(1,0));
	while(!q.empty()) {
		node t = q.top();
		q.pop();
		if(vis[t.to]) continue;
		vis[t.to] = true;
		ans += t.val;
		cnt++;
		if(!(cnt^n)) break;
		for(node i:edge[t.to]){
			if(vis[i.to]) continue;
			q.push(node(i.to,i.val));
		}
	}
	if(cnt^n) cout<<"orz";
	else cout<<ans;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	
	cin>>n>>m;
	int u,v,w;
	For(i,m) {
		cin>>u>>v>>w;
		edge[u].push_back(node{v,w});
		edge[v].push_back(node{u,w});
	}
	
	prim();
	
	
	return 0;
}

manacher

#include <bits/stdc++.h>
using namespace std;

#define Dec(i,a,n) for(register int i = a;i>=n;i--)


#define LOG2(x) __lg(x)
const int N = 2e7+5;
char s[N],a[N<<1];
int n,dp[N<<1];

void change() {
	n = strlen(s);
	int k = 0;
	a[k++] = '$';
	a[k++] = '#';
	For(i,0,n-1) {
		a[k++] = s[i];
		a[k++] = '#';
	} 
	a[k++] = '&';
	n = k;
}

void manacher() {
	int R = 0,C;
	For(i,1,n-1) {
		if(i < R) dp[i] = min(dp[(C<<1) - i],dp[C] + C - i);
		else dp[i] = 1;
		while(a[i + dp[i]] == a[i - dp[i]]) dp[i]++;
		if(dp[i] + i > R) {
			R = dp[i] + i;
			C = i;
		}
	} 
}

signed main() {
	char cc;
	int top = 0;
	while(cc = getchar()) s[top++] = cc;
	change();
	manacher();
	int ans = 1;
	For(i,0,n - 1) ans = max(ans,dp[i]);
	IO<<ans-1; 
	
	return 0;
}


失配树

#include <bits/stdc++.h>
using namespace std;

#define Dec(i,a,n) for(register int i = a;i>=n;i--)


#define LOG2(x) __lg(x)

const int N = 1e6+5;

char s[N];
int len,m,fa[N][22],dep[N]; 

void getfail() {
	fa[0][0]=fa[1][0]=0,dep[0]=0,dep[1]=1;
	for(int i=2,j=0;i<=len;++i)
	{
		while(j!=0&&s[j+1]!=s[i]) j=fa[j][0];
		if(s[j+1]==s[i]) ++j;
		fa[i][0]=j,dep[i]=dep[j]+1;
	}
}

int LCA(int &x,int &y) {
	if(dep[x] < dep[y]) swap(x,y);
	Dec(i,21,0) if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];
	Dec(i,21,0) if(fa[x][i] ^ fa[y][i]) x = fa[x][i],y = fa[y][i];
	return fa[x][0];
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	
	cin>>(s + 1);
	len = strlen(s + 1);
	getfail();
	cin>>m;
	For(i,1,21) For(j,1,len) fa[j][i] = fa[fa[j][i-1]][i-1];
	while(m--) {
		int p,q;
		cin>>p>>q;
		cout<<LCA(p,q)<<'\n';
	} 
	return 0;
}

扫描线 & 矩形面积并

#include <bits/stdc++.h>
using namespace std;
//省略头...
namespace my{
using namespace AllRangeApply_Define;
using namespace Atomic::normalSTD;
//using namespace Atomic::fastSTD;
//using namespace Atomic::SuperSTD;

const int N = 5e5 + 5;

namespace scanline{

#define ls (p<<1)
#define rs (p<<1 | 1)
#define mid ((pl + pr) >> 1)

int tag[N<<2];
int len[N<<2],xx[N<<2];

struct Scanline{
	int y,rx,lx;
	int inout;
	Scanline() {}
	Scanline(int y,int x2,int x1,int io) : y(y),rx(x2),lx(x1),inout(io) {}
}line[N<<2];

bool cmp(Scanline &a,Scanline &b) {
	return a.y < b.y;
}

void push_up(int p,int pl,int pr) {
	if(tag[p]) len[p] = xx[pr] - xx[pl];
	else if(pl + 1 == pr) len[p] = 0;
	else len[p] = len[ls] + len[rs];
}

void update(int p,int pl,int pr,int l,int r,int io) {
	if(l <= pl && pr <= r) {
		tag[p] += io;
		push_up(p,pl,pr);
		return;
	}
	if(pl + 1 == pr) return;
	if(l <= mid) update(ls,pl,mid,l,r,io);
	if(r > mid) update(rs,mid,pr,l,r,io);
	push_up(p,pl,pr);
}	

}

signed main(){
	speed_up(false);
	int n,t = 0;
	scanf("%lld",&n);
	int cnt = 0;
	while(n--) {
		int x1,x2,y1,y2;
		scanf("%lld%lld%lld%lld", &x1, &y1, &x2, &y2);
		scanline::line[++cnt] = scanline::Scanline(y1, x2, x1, 1);
		scanline::xx[cnt] = x1;
		scanline::line[++cnt] = scanline::Scanline(y2, x2, x1, -1);
		scanline::xx[cnt] = x2;
	}
	sort(scanline::xx + 1, scanline::xx + cnt + 1);
	sort(scanline::line + 1, scanline::line + cnt + 1, scanline::cmp);
	int num = unique(scanline::xx + 1, scanline::xx + cnt + 1) - scanline::xx - 1;
	memset(scanline::tag, 0, sizeof(scanline::tag));
	memset(scanline::len, 0, sizeof(scanline::len));
	int ans = 0;
	for(int i = 1;i<=cnt;i++) {
		int L,R;
		ans += scanline::len[1] * (scanline::line[i].y - scanline::line[i-1].y);
		L = lower_bound(scanline::xx + 1, scanline::xx + num + 1, 
											scanline::line[i].lx) - scanline::xx;
		R = lower_bound(scanline::xx + 1, scanline::xx + num + 1, 
											scanline::line[i].rx) - scanline::xx;
		scanline::update(1, 1, num, L, R, scanline::line[i].inout);
	}
	printf("%lld",ans);
	return 0;
}

}
signed main() {
	return my::main();
}
  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值