省选一轮模板复习

一、堆

#include <bits/stdc++.h>
using namespace std;
int n;
priority_queue < int, vector < int >, greater < int > > heap;
signed main () {
	scanf ("%d", &n);
	while (n --) {
		int op;
		scanf ("%d", &op);
		if (op == 1) {
			int x;
			scanf ("%d", &x);
			heap.push (x);
		}
		else if (op == 2) {
			printf ("%d\n", heap.top ());
		}
		else {
			heap.pop ();
		}
	}	
	return 0;
}

二、负环

#include <bits/stdc++.h>
using namespace std;
#define int long long
int T, n, m, cnt, head[2005], in[2005], vis[2005], dis[2005];
struct edge {
	int to, nxt, val;
} ed[6005];
inline void add_edge (int u, int v, int w) {
	cnt ++;
	ed[cnt].to = v;
	ed[cnt].val = w;
	ed[cnt].nxt = head[u];
	head[u] = cnt;
}
inline bool SPFA (int s) {
	for (int i = 1;i <= n; ++ i) in[i] = vis[i] = 0, dis[i] = 1e18;
	queue < int > q;
	q.push (s); vis[s] = 1; dis[s] = 0; in[s] ++;
	if (in[s] > n) return true;
	while (!q.empty ()) {
		int u = q.front ();
		q.pop (); vis[u] = 0;
		for (int i = head[u]; i ; i = ed[i].nxt) {
			int v = ed[i].to;
			int w = ed[i].val;
			if (dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				if (!vis[v]) {
					vis[v] = 1;
					in[v] ++;
					q.push (v);
					if (in[v] > n) return true;
				}
			}
		}
	}
	return false;
}
signed main () {
	scanf ("%lld", &T);
	while (T --) {
		scanf ("%lld %lld", &n, &m);
		cnt = 0;
		for (int i = 1;i <= n; ++ i) head[i] = 0;
		for (int i = 1;i <= m; ++ i) {
			int u, v, w;
			scanf ("%lld %lld %lld", &u, &v, &w);
			if (w >= 0) {
				add_edge (u, v, w);
				add_edge (v, u, w);
			}
			else {
				add_edge (u, v, w);
			}
		}
		if (SPFA (1)) printf ("YES\n");
		else printf ("NO\n");
	}
	return 0;
}

三、ST 表

#include <bits/stdc++.h>
using namespace std;
inline int read () {
	int x = 0, f = 0;
	char c = getchar ();
	for ( ; c < '0' || c > '9' ; c = getchar ()) f |= (c == '-');
	for ( ; c >= '0' && c <= '9' ; c = getchar ()) x = (x << 1) + (x << 3) + (c ^ 48);
	return x; 
}
int n, m, a[100005], lg[100005], st[100005][22];
inline int query (int l, int r) {
	int k = lg[r - l + 1];
	return max (st[l][k], st[r - (1 << k) + 1][k]);
}
signed main () {
	n = read (); m = read ();
	for (int i = 1;i <= n; ++ i) a[i] = read ();
	lg[0] = -1;
	for (int i = 1;i <= n; ++ i) lg[i] = lg[i >> 1] + 1;
	for (int i = 1;i <= n; ++ i) st[i][0] = a[i];
	for (int j = 1;j <= 21; ++ j) {
		for (int i = 1;i + (1 << j) - 1 <= n; ++ i) {
			st[i][j] = max (st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
		}
	}
	while (m --) {
		int l, r;
		l = read (); r = read ();
		printf ("%d\n", query (l, r));
	}
	return 0;
}

四、单调栈

#include <bits/stdc++.h>
using namespace std;
int n, a[3000005], q[3000005], T, ans[3000005];
signed main () {
	scanf ("%d", &n);
	for (int i = 1;i <= n; ++ i) scanf ("%d", &a[i]);
	for (int i = n;i >= 1; -- i) {
		while (T > 0 && a[q[T]] <= a[i]) T --;
		ans[i] = q[T];
		q[++ T] = i;
	}
	for (int i = 1;i <= n; ++ i) printf ("%d ", ans[i]);
	printf ("\n");
	return 0;
}

五、LCA

#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
int n, m, root, dp[N][20], dep[N], lg[N];
vector < int > tr[N];
inline void dfs (int u, int fa) {
	dep[u] = dep[fa] + 1;
	dp[u][0] = fa;
	for (int v : tr[u]) {
		if (v != fa) dfs (v, u);
	}
}
inline void init () {
	for (int j = 1;j <= 19; ++ j) {
		for (int i = 1;i <= n; ++ i) {
			dp[i][j] = dp[dp[i][j - 1]][j - 1];
		}
	}
}
inline int LCA (int x, int y) {
	if (dep[x] < dep[y]) swap (x, y);
	for (int i = lg[dep[x] - dep[y]];i >= 0; -- i) {
		if (dep[dp[x][i]] >= dep[y]) x = dp[x][i];
	}
	if (x == y) return x;
	for (int i = 19;i >= 0; -- i) {
		if (dp[x][i] != dp[y][i]) x = dp[x][i], y = dp[y][i];
	}
	return dp[x][0];
}
signed main () {
	scanf ("%d %d %d", &n, &m, &root);
	lg[0] = -1;
	for (int i = 1;i <= n; ++ i) lg[i] = lg[i >> 1] + 1;
	for (int i = 1;i < n; ++ i) {
		int u, v;
		scanf ("%d %d", &u, &v);
		tr[u].push_back (v);
		tr[v].push_back (u);
	}
	dep[root] = 1;
	dfs (root, 0);
	init ();
	while (m --) {
		int u, v;
		scanf ("%d %d", &u, &v);
		printf ("%d\n", LCA (u, v));
	}
	return 0;
}

六、线段树(区间乘法 & 加法,查询区间和)

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, m, p, a[100005];
int mul[400005], inc[400005], sum[400005];
inline void push_up (int u) {
	sum[u] = (sum[u << 1] + sum[u << 1 | 1]) % p;
}
inline void push_down (int u, int l, int r) {
	int mid = l + r >> 1;
	int l1 = mid - l + 1, l2 = r - mid;
	mul[u << 1] = mul[u << 1] * mul[u] % p;
	mul[u << 1 | 1] = mul[u << 1 | 1] * mul[u] % p;
	inc[u << 1] = (inc[u << 1] * mul[u] % p + inc[u]) % p;
	inc[u << 1 | 1] = (inc[u << 1 | 1] * mul[u] % p + inc[u]) % p;
	sum[u << 1] = (sum[u << 1] * mul[u] % p + inc[u] * l1 % p) % p;
	sum[u << 1 | 1] = (sum[u << 1 | 1] * mul[u] % p + inc[u] * l2 % p) % p;
	mul[u] = 1, inc[u] = 0;
}
inline void build (int u, int l, int r) {
	mul[u] = 1, inc[u] = 0;
	if (l == r) {
		sum[u] = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build (u << 1, l, mid);
	build (u << 1 | 1, mid + 1, r);
	push_up (u);
}
inline void cheng (int u, int l, int r, int x, int y, int v) {
	if (x <= l && r <= y) {
		sum[u] = sum[u] * v % p;
		inc[u] = inc[u] * v % p;
		mul[u] = mul[u] * v % p;
		return ;
	} 
	push_down (u, l, r);
	int mid = l + r >> 1;
	if (x <= mid) cheng (u << 1, l, mid, x, y, v);
	if (y > mid) cheng (u << 1 | 1, mid + 1, r, x, y, v);
	push_up (u);	
}
inline void add (int u, int l, int r, int x, int y, int v) {
	if (x <= l && r <= y) {
		sum[u] = (sum[u] + (r - l + 1) * v) % p;
		inc[u] = (inc[u] + v) % p;
		return ;
	}
	push_down (u, l, r);
	int mid = l + r >> 1;
	if (x <= mid) add (u << 1, l, mid, x, y, v);
	if (y > mid) add (u << 1 | 1, mid + 1, r, x, y, v);
	push_up (u);
}
inline int query (int u, int l, int r, int x, int y) {
	if (x <= l && r <= y) return sum[u];
	push_down (u, l, r);
	int mid = l + r >> 1, ans = 0;
	if (x <= mid) ans += query (u << 1, l, mid, x, y);
	if (y > mid) ans += query (u << 1 | 1, mid + 1, r, x, y);
	return ans % p;
}
signed main () {
	scanf ("%lld %lld %lld", &n, &m, &p);
	for (int i = 1;i <= n; ++ i) scanf ("%lld", &a[i]);
	build (1, 1, n);
	while (m --) {
		int op, x, y, k;
		scanf ("%lld %lld %lld", &op, &x, &y);
		if (op != 3) scanf ("%lld", &k);
		if (op == 1) {
			cheng (1, 1, n, x, y, k);
		}
		else if (op == 2) {
			add (1, 1, n, x, y, k);
		}
		else {
			printf ("%lld\n", query (1, 1, n, x, y));
		}
	}
	return 0;
}
posted @ 2023-03-31 16:28  CountingGroup  阅读(10)  评论(0编辑  收藏  举报