[Examination Summary] Happy Simulation Game_Day2

\ (T1 \)

Title description

There are \ (n \) gods in the fairy world, each god is represented by a special number of \ (1 ∼ n \) , the number of the ancestor \ (ChitongZ \) is \ (1 \) .
Except the Supreme Holy, Once upon a unified management ancestors \ (ChitongZ \) , the other \ (n - 1 \) bit has a unique respecting gods, and form a tree structure.
ancestors \ (ChitongZ \) in order to enhance the overall strength Xianjie , Advocate the gods to practice.
But every practice requires a golden pill, if a fairy does not have a golden pill, he needs to ask for one from his own master. If there is no master, then the master will ask His venerable master asks for one, and so on, until a golden pill is obtained, and the golden pill will be consumed after the practice.

\(Solution\)

Estimated \ (100pts \) , the array is opened only \ (60pts \)

In fact, there are many ways to do this question, I think of two, and record

\(EP.1\)

Similar to tree splitting, first make a \ (dfs \) , mark each point with \ (dfs \) order \ (id [x] \) , and maintain and cover with line tree

For a point \ (x \) , the closest marked point (ie \ (ans \) ) is the largest of all points that can cover it ( so \ (id \) , so do \ ( Take \ (max \) when pushdown \) , and convert it to the original answer when output

\(EP.2\)

Use and check maintenance

Save all operations, construct a tree, the state of the tree is after all operations are completed, then make a \ (dfs \) , if the point \ (x \) is marked, then \ (s [x] = x \) , Otherwise it points to \ (fa [x] \)

Then reverse the operation, that is, marking a point becomes the mark of removing a point, if the point is not marked, then point \ (s [x] \) to \ (fa [x] \)

Code

Only the code 233 for \ (EP.2 \)

#include<bits/stdc++.h>
#define ll long long
#define F(i, x, y) for(int i = x; i <= y; ++ i)
using namespace std;
int read();
const int N = 5e6 + 5;
const ll B1 = 37;
const ll P1 = 19260817;
const ll B2 = 137;
const ll P2 = 998244353; 
int n, m, x;
int s[N], d[N], fa[N], k[N]; 
ll ans1, ans2;
struct kk{
	int edge;
	char sta;
}Q[N];
int head[N], cnt;
struct node{
	int ver, next;
}a[N << 1];
void add(int x, int y)
{
	++ cnt;
	a[cnt].ver = y, a[cnt].next = head[x], head[x] = cnt;
}
void dfs(int x, int f)
{
	s[x] = d[x] ? x : f, fa[x] = f;
	for(int i = head[x]; i; i = a[i].next)
		if(a[i].ver != f)
			dfs(a[i].ver, x);	
}
int search(int x)
{
	return x == s[x] ? x : s[x] = search(s[x]);
}
int main()
{
	freopen("decomposition.in","r",stdin);
	freopen("decomposition.out","w",stdout);
	n = read(), m = read();
	F(i, 2, n) x = read(), add(x, i), add(i, x);
	F(i, 1, m)
	{
		Q[i].sta = read(), Q[i].edge = read();
		if(Q[i].sta == 2) ++ d[Q[i].edge];
	} 
	dfs(1, 0), s[1] = 1, fa[1] = 1;
	for(int i = m; i >= 1; -- i)
	{
		if(Q[i].sta == 1) k[i] = search(Q[i].edge);
		else 
		{
			-- d[Q[i].edge];
			if(! d[Q[i].edge]) s[Q[i].edge] = fa[Q[i].edge];
		}
	}
	F(i, 1, m) if(k[i])
		ans1 = (ans1 * B1 + k[i]) % P1, ans2 = (ans2 * B2 + k[i]) % P2;
	printf("%lld %lld", ans1, ans2);
	return 0;
}
int read()
{
	int x = 0;
	char c = getchar();
	while(c < '0' || c > '9') c = getchar();
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x;
}

\(T2\)

Title description

There are \ (n \) individuals who enter the viewing hall in turn and watch \ (Weathering \ with \ You \) . The
viewing hall has only one row of seats, and the first \ (1 \) individual will choose the first \ (1 \) Sitting down.
Because the air conditioning in the movie theater is broken, it is very hot. When everyone enters afterwards, he will choose an empty seat as far as possible from the nearest person who has sat down.
If there are multiple empty seats, the nearest The person is the same distance, then he will randomly choose one of them.
If two people choose the position next to each other, they will be dissatisfied.
In order to satisfy everyone, how many seats does the movie theater need?

\(Solution\)

It can be drawn according to various playing rules

\[f(x) = x + 2^{1+⌊log_2(x−2)⌋}. \]

Then write with high precision

The more convenient way to write is to use \ (2 \) to continuously multiply upwards, judge the size while multiplying, and finally add a \ (n \)

In this way, as long as writing high precision multiplies low precision, judging size, high precision addition, it is easier to write

There are also special cases, \ (f (1) = 1 \) , \ (f (2) = 3 \) , I did n’t expect that then only \ (95pts \)

Code

#include<bits/stdc++.h>
#define F(i, x, y) for(int i = x; i <= y; ++ i)
using namespace std;
int read();
const int N = 2e3 + 5;
char z;
int a[N], alen;
int b[N], blen;
int c[N], clen;
void mul(int b[])
{
	int x = 0;
	F(i, 1, blen) x += b[i] * 2, b[i] = x % 10, x = x / 10;
	if(x) b[++ blen] = x;
}
bool comp(int a[], int b[])
{
	int x = 2, clen = blen;
	F(i, 1, blen) c[i] = b[i];
	F(i, 1, clen)
	{
		c[i] += x, x = c[i] / 10, c[i] %= 10;
		if(! x) break;
	}
	if(x) c[++ clen] = x;
	if(alen != clen) return alen > clen;
	for(int i = alen; i >= 1; -- i)
		if(a[i] != c[i]) return a[i] > c[i];
	return true;
}
int main()
{
	freopen("tenki.in","r",stdin);
	freopen("tenki.out","w",stdout);
	while(scanf("%c", &z) != EOF) c[++ alen] = z - '0';
	-- alen;
	F(i, 1, alen) a[alen - i + 1] = c[i];
	if(alen == 1 && (a[1] == 1 || a[1] == 2))
	{
		puts(a[1] == 1 ? "1" : "3");
		return 0;
	}
	blen = 1, b[blen] = 2;
	while(comp(a, b)) mul(b);
	memset(c, 0, sizeof(c));
	F(i, 1, max(alen, blen))
	{
		c[i] = c[i] + a[i] + b[i];
		c[i + 1] = c[i] / 10, c[i] %= 10;
	}
	clen = max(alen, blen);
	if(c[clen + 1]) ++ clen;
	for(int i = clen; i >= 1; -- i) printf("%d", c[i]); 
	return 0;
}
/*
q = (log2 (n - 2)) + 1;
ans = 2 ^ q + n;
*/

\ (T3 \)

Title description

Given a positive integer \ (k \) and a rooted tree with \ (n \) nodes rooted at \ (1 \) , the edges have lengths.
Remember \ (LCA (a, b) \) Indicates the nearest common ancestor of \ (a \) and \ (b \) on the tree, \ (dist (a) \) indicates the distance from the root of the tree to \ (a \) .
Each node can be black or white, initial The color of each node is white.
Perform m operations, and each operation is one of the following two forms:
modify operation: give a modify node \ (x \) , dye node \ (x \) black. Make sure that \ (x \) is white before dyeing.
Query operation: Give a query node \ (x \) , record the set formed by all black dots as \ (S \) , and find the value of the following formula:

\[\sum_{y∈S}F( dist ( LCA ( x, y ) ) ) \]

The function \ (F \) is defined as,

\[F(x) =\sum\limits_{i=1}^xi^k \]

Since the answer may be large, it is only necessary to output the result of modulo of the answer pair \ (P = 998244353 \)

\(Solution\)

The difficulty of this question:

\ (1. \) The question is more circumvent, the required answer function is a set of functions, it is easy to get wrong.
\ (2. \) List the formula and simplify the formula, disassemble the fixed value and the value to be maintained

Lived for half an afternoon \ (+ \) Half night for self-study, exhausted ... but really a good question! !

\(Code\)

#include<bits/stdc++.h>
#define ll long long
#define ls k << 1
#define rs (k << 1) + 1
#define mid ((l + r) >> 1)
#define F(i, x, y) for(int i = x; i <= y; ++ i)
using namespace std;
int read();
const int N = 1e5 + 5;
const int M = 1e7 + 5;
const int mod = 998244353;
int n, m, s;
ll x, y, num, vis[N], f[M], dist[N];
ll tree[N << 2], atree[N << 2], tag[N << 2], a[N];
ll dep[N], size[N], fa[N], son[N], id[N], top[N];
ll head[N], cnt, ver[N << 1], edge[N << 1], nxt[N << 1];
void add(int x, int y, int z)
{
	ver[++ cnt] = y, edge[cnt] = z, nxt[cnt] = head[x], head[x] = cnt;
}
ll qpower(ll x, int y)
{
	ll res = 1;
	while(y)
	{
		if(y & 1) res = res * x % mod;
		x = x * x % mod, y >>= 1;
	}
	return res;
}
void dfs1(int x, int ffa)
{
	dep[x] =dep[ffa] + 1, size[x] = 1, fa[x] = ffa;
	int maxn = -1;
	for(int i = head[x]; i; i = nxt[i])
		if(ver[i] != ffa)
		{
			dist[ver[i]] = dist[x] + edge[i], dfs1(ver[i], x), size[x] += size[ver[i]];
			if(size[ver[i]] > maxn) son[x] = ver[i], maxn = size[ver[i]];
		}
}
void dfs2(int x, int topfa, int ffa)
{
	id[x] = ++ num, top[x] = topfa;
	a[id[x]] = (f[dist[x]] - f[dist[ffa]] + mod) % mod;
	if(! son[x]) return;
	dfs2(son[x], topfa, x);
	for(int i = head[x]; i; i = nxt[i])
		if(ver[i] != fa[x] && ver[i] != son[x])
				dfs2(ver[i], ver[i], x);
}
void pushup(int l, int r, int k)
{
	atree[k] = (atree[ls] + atree[rs]) % mod;
}
void build(int l, int r, int k)
{
	if(l == r) 
	{
		tree[k] =  a[l] % mod;
		return;
	}
	build(l, mid, ls);
	build(mid + 1, r, rs);
	tree[k] = (tree[ls] + tree[rs]) % mod; 
}
void pushdown(int l, int r, int k)
{
	if(! tag[k]) return;
	atree[ls] = (tree[ls] * tag[k] % mod + atree[ls]) % mod;
	atree[rs] = (tree[rs] * tag[k] % mod + atree[rs]) % mod;
	tag[ls] += tag[k], tag[rs] += tag[k];
	tag[k] = 0;
}
void modify(int l, int r, int k, int x, int y, int v)
{
	if(l >= x && r <= y) 
	{
		atree[k] = (tree[k] * v % mod + atree[k]) % mod, tag[k] += v;
		return;
	}
	pushdown(l, r, k);
	if(x <= mid) modify(l, mid, ls, x, y, v);
	if(y > mid) modify(mid + 1, r, rs, x, y, v);
	pushup(l, r, k);
}
ll query(int l, int r, int k, int x, int y)
{
	if(l >= x && r <= y) return atree[k];
	pushdown(l, r, k);
	ll res = 0;
	if(x <= mid) res = (res + query(l, mid, ls, x, y)) % mod;
	if(y > mid) res = (res + query(mid + 1, r, rs, x, y)) % mod;
	return res;
}
void modify_range(int x)
{
	if(vis[x]) return;
	vis[x] = 1;	
	while(top[x] != 1)
	{
		modify(1, n, 1, id[top[x]], id[x], 1);
		x = fa[top[x]];
	}
	modify(1, n, 1, 1, id[x], 1);
}
ll query_range(int x)
{
	ll res = 0; 
	while(top[x] != 1)
	{
		res = (res + query(1, n, 1, id[top[x]], id[x])) % mod;
		x = fa[top[x]];
	}
	res = (res + query(1, n, 1, 1, id[x])) % mod;
	return res;
}
int main()	
{
	freopen("mafumafu.in","r",stdin);
	freopen("mafumafu.out","w",stdout);
	n = read(), m = read(), s = read();
	F(i, 1, M - 1) f[i] = (f[i - 1] + qpower(i, s) % mod) % mod;
	F(i, 2, n) x = read(), y = read(), add(x, i, y), add(i, x, y);
	dfs1(1, 0), dfs2(1, 1, 0), build(1, n, 1);
	while(m --)
	{
		y = read(), x = read();
		if(y == 1) modify_range(x);
		if(y == 2) printf("%lld\n", query_range(x));
	}
	return 0;
}
int read()
{
	int x = 0, f = 1;
	char c = getchar();
	while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x * f;
}

to sum up

Ranking \ (: 5/17 \)

Estimated score \ (: 100 + 100 + 0 \)

Actual score \ (: 60 + 95 + 0 \)

\ (1. \) are all \ (0202 \) . Why do I still make this kind of mistake when the array is opened . . .
\ (2. \)\ (0202 \) How can I still not consider this kind of error in special cases . . .

Generally speaking, it ’s okay today. I adjusted the state of the exam and tried my best to get the score. In fact, there are still half an hour left after writing the first two questions. I hit the \ (t3 \) violence, but unfortunately I do n’t have time to adjust, but this kind of The habit is to stick to it, seize every minute and every second

Guess you like

Origin www.cnblogs.com/Bn_ff/p/12682101.html