zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    细说VMWare加入OpenStack
    云计算和大数据的崛起
    HTML5 Web app开发工具Kendo UI Web教程:如何配置Kendo UI Calendar
    Android:增强目录选择器对话框
    Gartner指明2014年几大战略技术趋势
    Android开发人员终于在“app-构建控制台”中获得分析
    谷歌升级Android分析应用程序
    Android是Windows开发人员可选择的下一个平台
    Greek
    为什么质数有无穷多个
  • 原文地址:https://www.cnblogs.com/little-uu/p/14015311.html
Copyright © 2011-2022 走看看