2019ICPC南昌邀请赛

A - PERFECT NUMBER PROBLEM

题意

找到前五个因数之和(除了自己)是本身的数

思路

(nsqrt n) 暴力打表

6, 28, 496, 8128, 33550336

M - Subsequence

题意

询问是否是子序列

思路

直接暴力

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

int mp[26][100010];
int cnt[26];
char s[100010], p[1010];
int T;
int main() {
	scanf("%s", s + 1);
	int x = strlen(s + 1);
	for (int i = 1; i <= x; i++) {
		mp[s[i] - 'a'][cnt[s[i] - 'a']++] = i;
	}
	scanf("%d", &T); getchar();
	while (T--) {
		scanf("%s", p + 1);

		int now = 0, f = 1;
		int len = strlen(p + 1);
		for (int i = 1; i <= len; i++) {
            int idx = p[i] - 'a';
			int pos = upper_bound(mp[idx], mp[idx] + cnt[idx], now) - mp[idx];
			if (pos == cnt[idx]) {
				f = 0;
				break;
			}
			now = mp[idx][pos];
		}
		if (f)puts("YES");
		else puts("NO");
	}
}

H - Coloring Game

(f[n] = 2*2*3^{n-2})

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

const int mod = 1000000007;

int qpow(int a, int p) {
	int ans = 1;
	while (p) {
		if (p & 1)ans = (ans * a) % mod;
		a = a * a % mod;
		p >>= 1;
	}
	return ans;
}

signed main() {
	int n; cin >> n;
	if (n == 1)cout << 1 << endl;
	else cout << 4 * qpow(3, n - 2) % mod << endl;
}

K - MORE XOR

找规律

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

const int N = 1e5 + 10;
int A[N];

int T, n, m;
int f[N];

int main() {
	scanf("%d", &T);
	while (T--) {
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) {
			scanf("%d", A + i);
			f[i] = A[i];
			if (i > 4)f[i] ^= f[i - 4];
		}
		scanf("%d", &m);
		while (m--) {
			int l, r;
			scanf("%d%d", &l, &r);
			if (l == r) {
				printf("%d
", A[l]);
				continue;
			}
			int len = r - l + 1;
			int ans = 0;
			if (len % 2 == 0) {
				int x = len / 2;
				if (x % 2 == 0)ans = 0;
				else ans = f[r] ^ f[l + 1] ^ A[l + 1] ^ f[r - 1] ^ f[l] ^ A[l];;
			}
			else {
				int x = len / 2;
				if (x % 2 == 0) {
					ans = f[r] ^ f[l] ^ A[l];
				}
				else {
					ans = f[r - 1] ^ f[l + 1] ^ A[l + 1];
				}
			}
			printf("%d
", ans);
		}
	}
}

J - Distance on the tree

查询树上路径上边权小于等于 (k) 的边数

写的树剖加主席树,挂了

/*
 * @Author: zhl
 * @Date: 2020-11-9 20:36:59
 */
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i = a;i <= b;i++)
#define repE(i,u) for(int i = head[u];i;i = E[i].next)
#define mid ((l+r)>>1)

using namespace std;
const int N = 5e5 + 10;
int A[N];
int n, m;

struct Edge {
	int to, next, w;
}E[N << 1];

int head[N], tot;
void addEdge(int from, int to,int w) {
	E[++tot] = Edge{ to,head[from],w };
	head[from] = tot;
}

int fa[N], sz[N], Tfa[N], dep[N], son[N];

//dfs1处理dep,sz,fa,son(重儿子)
void dfs1(int u, int p) {
	fa[u] = p;
	dep[u] = dep[p] + 1;
	sz[u] = 1;
	int mx = -1;
	repE(i, u) {
		int v = E[i].to;
		if (v == p)continue;
		dfs1(v, u);
		sz[u] += sz[v];
		if (sz[v] > mx)mx = sz[v], son[u] = v;
	}
}

int cnt;
int id[N], val[N], top[N];
//dfs2 剖分树链
void dfs2(int u, int topf, int w) {
	id[u] = ++cnt;
	
	val[cnt] = w;
	top[u] = topf;
	if (!son[u])return;

	int x = 0;
	repE(i, u)if (E[i].to == son[u]) x = E[i].w;
	dfs2(son[u], topf, x);

	repE(i, u) {
		int v = E[i].to;
		if (v == fa[u] or v == son[u])continue;
		dfs2(v, v, E[i].w);
	}
}




int W[N];//边权
int root[N]; 
int cntW;
int getid(int x) {
	return lower_bound(W + 1, W + cntW + 1, x) - W;
}
int L[N << 5], R[N << 5], sum[N << 5];
int Tot;


int build(int l, int r) {
	int u = ++Tot;
	sum[u] = 0;
	if (l < r) {
		L[u] = build(l, mid);
		R[u] = build(mid + 1, r);
	}
	return u;
}

int insert(int pre, int l, int r, int pos) {
	int u = ++Tot;
	L[u] = L[pre];
	R[u] = R[pre];
	sum[u] = sum[pre] + 1;

	if (l >= r)return u;

	if (pos <= mid) {
		L[u] = insert(L[pre], l, mid, pos);
	}
	else {
		R[u] = insert(R[pre], mid + 1, r, pos);
	}
	return u;
}
int query(int rt_x, int rt_y,int l,int r, int k) {
	if (l == r) {
		return sum[rt_y] - sum[rt_x];
	}
	int num = sum[L[rt_y]] - sum[L[rt_x]];//区间内,左半区间的数的数量

	if (k <= mid) return query(L[rt_x], L[rt_y], l, mid, k);
	else return num + query(R[rt_x], R[rt_y], mid + 1, r, k);

	return 0;
}
int query_path(int a, int b,int k) {
	int ans = 0; int x, y;
	int v = upper_bound(W + 1, W + cntW + 1, k) - W - 1;
	if (!v)return 0;
	while (top[a] != top[b]) {
		if (dep[top[a]] < dep[top[b]])swap(a, b);
		x = id[top[a]]; y = id[a];
		ans += query(root[x-1], root[y], 1, cntW, v);
		a = fa[top[a]];
	}
	if (a == b)return ans;
	if (dep[a] > dep[b])swap(a, b);
	x = id[a]; y = id[b];
	ans += query(root[x-1], root[y], 1,cntW, v);
	return ans;
}

int main() {
	scanf("%d%d", &n, &m);

	for (int i = 1; i < n; i++) {
		int x, y, z;
		scanf("%d%d%d", &x, &y, &z);
		W[i] = z;
		addEdge(x, y, z); addEdge(y, x, z);
	}
	W[n] = 0x3f3f3f3f;
	sort(W + 1, W + n + 1);
	cntW = unique(W + 1, W + n + 1) - W - 1;
	root[0] = build(1, cntW);

	dfs1(1, 0);
	dfs2(1, 1, 0x3f3f3f3f);

	for (int i = 1; i <= n; i++) {
		root[i] = insert(root[i - 1], 1, cntW, getid(val[i]));
	}

	while (m--) {
		int a, b, k;
		scanf("%d%d%d", &a, &b, &k);
		printf("%d
", query_path(a, b, k));
	}
}

换了一个写法,就 A 了???

int query_path(int a, int b, int k) {
	int lca = LCA(a, b);
	int v = upper_bound(W + 1, W + 1 + cntW, k) - W - 1;
	if (!v)return 0;
	int ans = query(root[0], root[a], 1, cntW, 1, v) + query(root[0], root[b], 1, cntW, 1, v) - 2 * query(root[0], root[lca], 1, cntW, 1, v);
	//if (val[lca] <= k)ans--;
	return ans;
}
/*
 * @Author: zhl
 * @Date: 2020-11-10 20:36:59
 */
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i = a;i <= b;i++)
#define repE(i,u) for(int i = head[u];i;i = E[i].next)
#define mid ((l+r)>>1)

using namespace std;
const int N = 5e5 + 10;
int n, m;

struct Edge {
	int to, next, w;
}E[N << 1];

int head[N], tot;
void addEdge(int from, int to, int w) {
	E[++tot] = Edge{ to,head[from],w };
	head[from] = tot;
}

int fa[N], sz[N], Tfa[N], dep[N], son[N];

//dfs1处理dep,sz,fa,son(重儿子)
void dfs1(int u, int p) {
	fa[u] = p;
	dep[u] = dep[p] + 1;
	sz[u] = 1;
	int mx = -1;
	repE(i, u) {
		int v = E[i].to;
		if (v == p)continue;
		dfs1(v, u);
		sz[u] += sz[v];
		if (sz[v] > mx)mx = sz[v], son[u] = v;
	}
}

int cnt;
int id[N], val[N], top[N];
//dfs2 剖分树链





int W[N];//边权
int root[N];
int cntW;
int getid(int x) {
	return lower_bound(W + 1, W + cntW + 1, x) - W;
}
int L[N << 5], R[N << 5], sum[N << 5];
int Tot;


int build(int l, int r) {
	int u = ++Tot;
	if (l < r) {
		L[u] = build(l, mid);
		R[u] = build(mid + 1, r);
	}
	return u;
}

int insert(int pre, int l, int r, int pos) {
	int u = ++Tot;
	L[u] = L[pre];
	R[u] = R[pre];
	sum[u] = sum[pre] + 1;

	if (l >= r)return u;

	if (pos <= mid) {
		L[u] = insert(L[pre], l, mid, pos);
	}
	else {
		R[u] = insert(R[pre], mid + 1, r, pos);
	}
	return u;
}
int query(int rt_x, int rt_y, int l, int r, int Lq, int Rq) {
	if (Lq <= l and r <= Rq) {
		return sum[rt_y] - sum[rt_x];
	}
	int num = sum[L[rt_y]] - sum[L[rt_x]];//区间内,左半区间的数的数量
	int res = 0;

	if (Lq <= mid) res += query(L[rt_x], L[rt_y], l, mid, Lq, Rq);
	if (Rq > mid) res += query(R[rt_x], R[rt_y], mid + 1, r, Lq, Rq);
	return res;
}

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])swap(a, b);
	return a;
}

int query_path(int a, int b, int k) {
	int lca = LCA(a, b);
	int v = upper_bound(W + 1, W + 1 + cntW, k) - W - 1;
	if (!v)return 0;
	int ans = query(root[0], root[a], 1, cntW, 1, v) + query(root[0], root[b], 1, cntW, 1, v) - 2 * query(root[0], root[lca], 1, cntW, 1, v);
	//if (val[lca] <= k)ans--;
	return ans;
}

void dfs2(int u, int topf, int w) {
	id[u] = ++cnt;

	val[cnt] = w;
	top[u] = topf;
	root[u] = insert(root[fa[u]], 1, cntW, getid(w));
	if (!son[u])return;

	int x = 0;
	repE(i, u)if (E[i].to == son[u]) x = E[i].w;

	dfs2(son[u], topf, x);

	repE(i, u) {
		int v = E[i].to;
		if (v == fa[u] or v == son[u])continue;
		dfs2(v, v, E[i].w);
	}
}

int main() {
	scanf("%d%d", &n, &m);

	for (int i = 1; i < n; i++) {
		int x, y, z;
		scanf("%d%d%d", &x, &y, &z);
		W[i] = z;
		addEdge(x, y, z); addEdge(y, x, z);
	}
	W[n] = 0x3f3f3f3f;
	sort(W + 1, W + n + 1);
	cntW = unique(W + 1, W + n + 1) - W - 1;
	root[0] = build(1, cntW);

	dfs1(1, 0);
	dfs2(1, 1, 0x3f3f3f3f);



	while (m--) {
		int a, b, k;
		scanf("%d%d%d", &a, &b, &k);
		printf("%d
", query_path(a, b, k));
	}
}

/*
5 400
1 2 7
1 3 4
2 4 5
3 5 2
2 3 1000000000
4 5 1000000000
*/
原文地址:https://www.cnblogs.com/sduwh/p/13955590.html