2020.10.06 Training Match Supplement

The 2019 ICPC Asia Hong Kong Regional Contest

B. Binary Tree

  • This question actually takes away a perfect binary tree, then the number of nodes is reduced by an odd number, this is inevitable ( 2 N − 1 2^N-12N1 must be an odd number). Therefore, if the number of nodes in the binary tree is odd, Alice wins, otherwise Bob wins.
  • The code is omitted.

E. Erasing Numbers

  • Ideas:
  • Choose 3 consecutive numbers to delete the median or delete the larger and the smaller and leave the median. I feel that this kind of question has been asked many times from last year to this year. Basically, it is the current number as the standard, and then compare it to others. The small ones are all 0, and the bigger ones are all 1, and then do it.
  • The necessary and sufficient condition that he can keep is that there are only 6 forms of 01X, 0X1, 1X0, 10X, X01, X10, so in fact, can you delete some numbers so that the number of 0 and 1 is the same, as long as the number of 01 and is the same , Regardless of the arrangement of 011 or the arrangement of 010, one 0 and one 1 are deleted.
  • So, if we have 7 numbers, see if 6 can be left. There are 5 0s and 1 1 at this time, so at least 4 0s need to be deleted. Only when three zeros are continuous can the number of zeros be less than the number of ones. If there are at least two consecutive groups of three zeros, then the number of zeros deleted can be 4 less than the number of ones.
  • Therefore, for greater than (n + 1) / 2 (n + 1) / 2(n+1 ) / 2 the number x, see how many consecutive three 0s, if there are more thanabs ((n + 1) / 2 − x) abs((n + 1) / 2-x)abs((n+1)/2x ) , then this number can be retained.
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int maxn = 5010;
int a[maxn], N;

int del(int l, int r, int pos, bool flag){
    
    
	int now = 0, res = 0;
	for(int i = l; i <= r; i++){
    
    
		if(flag){
    
    
			if(a[i] > a[pos]){
    
    
				if(++now == 3) now = 1, res++;
			}
			else if(--now == -1) now = 0;
		}
		else{
    
    
			if(a[i] < a[pos]){
    
    
				if(++now == 3) now = 1, res++;
			}
			else if(--now == -1) now = 0;
		}
	}
	return res;
}
int main(){
    
    
	int T;
	scanf("%d", &T);
	while(T--){
    
    

		scanf("%d", &N);
		for(int i = 1; i <= N; i++){
    
    
			scanf("%d", &a[i]);
		}
		bool is_small = false;

		for(int i = 1; i <= N; i++){
    
    
			if(a[i] < (N + 1) / 2) is_small = true;
			else is_small = false;
			printf("%d", del(1, i - 1, i, is_small) + del(i + 1, N, i, is_small) >= abs((N + 1) / 2 - a[i]));
		}
		printf("\n");
	}
	return 0;
}

Similar topics: Eliminate++

Problem solution This
problem needs to be optimized with a line segment tree.

G. Game Design

  • Idea: In fact, it is to see how much a subtree can contribute. If you need to contribute an odd number, then connect one more node, if it is an even number, then connect two subtrees to contribute cnt / 2 and 2 respectively.
  • Don’t forget that each node itself can also contribute one, so each node, cnt–.
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100010;
int w[maxn];
int N, K, par[maxn];
int dfs(int u, int cnt, int fa) {
    
    
	par[u] = fa;
	cnt--;
	if (cnt == 0) return w[u] = 1;
	else if (cnt & 1)  return w[u] = dfs(++N, cnt, u);
	else {
    
    
		int l = dfs(++N, 2, u);
		int r = dfs(++N, cnt / 2, u);
		return w[u] = l + r; 
	}
}
int main() {
    
    
	scanf("%d", &K);
	if (K == 1) {
    
    
		printf("2\n1\n1 2\n");
		return 0;
	}
	dfs(++N, K, -1);
	printf("%d\n", N);
	for (int i = 2; i <= N; i++) printf("%d%c", par[i], i == N ? '\n' : ' ');
	for (int i = 1; i <= N; i++) printf("%d%c", w[i], i == N ? '\n' : ' ');
	return 0;
}

J. Junior Mathematician

  • Digital dp
  • The meaning of the title, define f (x) f(x)f ( x ) is the sum of the product of two digits of a number.
  • After learning digital dp, I will make up this question.

Guess you like

Origin blog.csdn.net/qq_45812711/article/details/108940452