20201121模拟

期望100+30+30,实际100+30+30

T1

problem

(1 ightarrow n)的全排列中,与给出的排列构成的二叉查找树形式相同的排列个数

solution

我们发现二叉查找树中的左子树中数的相对位置不变,右子树中数的相对位置不变。

所以在排列中几组数的相对位置是不变的,但是在他们中间可以插入一些别的数,且这些数也是具有相对位置的

考虑一组具有相对位置的(m)数的位置的排列情况,就可以看成是在(n)个物品里选(m)个物品的排列组合

左右子树互不影响,根据乘法原理求出全部的方案数

code
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
int read(){
	int x = 1,a = 0;char ch = getchar();
	while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
	while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
	return x*a;
}
const int maxn = 3005,mod = 1e9+7;
int m,n;
int a[maxn],son[maxn][5];
void build(){
	for (int i = 2;i <= n;i++){
		for (int j = 1;j <= n;){
			if (a[i] < a[j]){
				if (son[j][1]) j = son[j][1];
				else {son[j][1] = i;break;}
			}
			else{
				if (son[j][2]) j = son[j][2];
				else {son[j][2] = i;break;}
			}
		}
	}
}
int siz[maxn];
void dfs1(int x){
	siz[x] = 1;
	if (son[x][1]) dfs1(son[x][1]);
	if (son[x][2]) dfs1(son[x][2]);
	siz[x] += siz[son[x][1]]+siz[son[x][2]];
}
int C[maxn][maxn];
void init(){
	C[0][0] = 1;
	C[1][0] = C[1][1] = 1;
	for (int i = 1;i <= 2000;i++){
		C[i][0] = 1;
		for (int j = 1;j <= i;j++){
			C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
		}
	}
}
int ans[maxn];
void dfs2(int x){
	if (son[x][1]) dfs2(son[x][1]);
	if (son[x][2]) dfs2(son[x][2]);
	ans[x] = C[siz[son[x][1]]+siz[son[x][2]]][siz[son[x][1]]]%mod*ans[son[x][1]]%mod*ans[son[x][2]]%mod;
}
signed main(){
	freopen("bst.in","r",stdin);
	freopen("bst.out","w",stdout);
	m = read();
	init();
	for (int i = 1;i <= m;i++){
		n = read();
		memset(son,0,sizeof(son));
		for (int j = 1;j <= n;j++) a[j] = read(),ans[j] = 1;
		ans[0] = 1;
		build();dfs1(1);
		dfs2(1);
		printf("%lld
",ans[1]-1);
	}
	return 0;
}

T3

solution

正解,线段树合并???这是个啥,并不会做。暴力30分,把所有能走到的点记录下来,最后统一统计一下颜色出现的次数

code
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
int read(){
	int x = 1,a = 0;char ch = getchar();
	while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
	while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
	return x*a;
}
const int maxn = 1e4+10;
int n,m,op,tmp;
int c[maxn];
struct node{
	int to,nxt,w;
}ed[maxn*2];
int head[maxn],tot;
void add(int u,int to,int w){
	ed[++tot].to = to;
	ed[tot].nxt = head[u];
	ed[tot].w = w;
	head[u] = tot;
}
int top;
int vis[maxn],col[maxn],st[maxn];
void dfs(int x,int k){
	if (vis[x]) return;
	vis[x] = 1;st[++top] = x;
	for (int i = head[x];i;i = ed[i].nxt){
		int to = ed[i].to;
		if (ed[i].w > k) continue;
		dfs(to,k);
	}
}
signed main(){
	freopen("garden.in","r",stdin);
	freopen("garden.out","w",stdout);
	n = read(),m = read(),op = read();
	for (int i = 1;i <= n;i++) c[i] = read();
	for (int i = 1;i <= m;i++){
		int x = read(),y = read(),w = read();
		add(x,y,w),add(y,x,w);
	}
	int q = read(),lst = 0;
	for (int i = 1;i <= q;i++){
		memset(st,0,sizeof(st));
		memset(col,0,sizeof(col));
		memset(vis,0,sizeof(vis));
		int a = read(),b = read();
		if (op == 2) a ^= lst,b ^= lst;
	//	cout<<a<<" "<<b<<endl;
		top = 0;tmp = 0;
		dfs(a,b);
		for (int j = 1;j <= top;j++){
	//	cout<<st[j]<<" ";
			col[c[st[j]]]++;
			if (col[tmp] < col[c[st[j]]]||(col[tmp] == col[c[st[j]]]&&tmp > c[st[j]])) tmp = c[st[j]]; 
		}
	//	cout<<endl;
		lst = tmp;
		printf("%lld
",lst);
	}
	return 0;
}

T4

solution

继续暴力,能走就连边,查询暴力dfs看是否联通

code
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
int read(){
	int x = 1,a = 0;char ch = getchar();
	while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
	while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
	return x*a;
}
const int maxn = 1e6+10;
int n,cnt;
int fa[maxn];
struct node{
	int x,y;
}a[maxn];
struct edge{
	int to,nxt;
}ed[maxn];
int head[maxn],tot;
void add(int u,int to){
	ed[++tot].to = to;
	ed[tot].nxt = head[u];
	head[u] = tot;
}
int vis[maxn];
void dfs(int x){
	if (vis[x]) return;
	vis[x] = 1;
	for (int i = head[x];i;i = ed[i].nxt){
		int to = ed[i].to;
		dfs(to);
	}
}
signed main(){
	freopen("interval.in","r",stdin);
	freopen("interval.out","w",stdout);
	n = read();
	for (int i = 1;i <= n;i++){
		int op = read();
		if (op == 1){
			a[++cnt].x = read(),a[cnt].y = read();
			for (int j = cnt-1;j >= 1;j--){
				if ((a[j].x > a[cnt].x&&a[j].x < a[cnt].y)||(a[j].y > a[cnt].x&&a[j].y < a[cnt].y)){
					add(j,cnt);
				}
				if ((a[cnt].x > a[j].x&&a[cnt].x < a[j].y)||(a[cnt].y > a[j].x&&a[cnt].y < a[j].y)){
					add(cnt,j);
				}
			}
		}
		if (op == 2){
			memset(vis,0,sizeof(vis));
			int x = read(),y = read();
			dfs(x);
			if (vis[y]) printf("YES
");
			else printf("NO
");
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/little-uu/p/14015311.html