zoukankan      html  css  js  c++  java
  • 【8.12测试】辉夜的二叉树

    辉夜的二叉树

    【题目背景】

    又是某高中学生会无聊的一天。可爱的辉夜在繁忙的学习之余,仍抽空欣赏她 n 个节点的二叉树。

    【问题描述】

    突然,由于某种神秘力量,她的二叉树每个节点都带上了一个权值。她看到这个神奇的二叉树,想到了一条水题。由于真的太水了,她又魔改了一下。她看着你好奇的目光,偷偷告诉了你题目。

    给出一棵 n 个节点,节点有权值的二叉树,第 i 个点的点权为 a[i]。有 3 种操作(修改或查询)

    1. 修改点 x 的点权。

    2. 对于点 x 的子树,交换每个节点的左右儿子。

    3. 选择一个点 x ,从根开始往下走,假设当前走到点 y ,若 a[x]<= a[y],则向 y 的左儿子走,否则向 y 的右儿子走,问能否走到节点 x 。

    然而辉夜大小姐想起了 自己的题被 暴力踩标程 的恐惧,给了非常友善的暴力分。

    【输入格式】

    第一行 2 个整数 n ,m ,表示二叉树的节点个数与操作数。

    接下来 n行

    第 i 行 3 个整数。a[i],lc ,rc ,分别表示点 i 的初始权值,左儿子的编号,右儿子的编号。

    接下来 m行

    每行第一个数 ops ,表示操作类型,如上所述。

    若 ops=1 ,接下来两个整数 x   权值改为 y。

    若 ops=2 ,接下来一个整数 x  ,表示把点 x 的子树每个点的左右儿子交换

    若 ops=3 ,接下来一个整数 x  ,如上所述。

    【输出格式】

    对于每个 ops=3 的操作,输出 YES 或 NO 。

    【样例输入】

    3 7

    10 2 3

    5 0 0

    5 0 0

    3 1

    3 2

    3 3

    1 3 100

    3 3

    2 1

    3 3

    【样例输出】

    YES

    YES

    NO

    YES

    NO

    【数据范围】

    对于 10% 数据,n,m <=5000

    另有 35% 数据,没有操作 2 。

    对于 100% 数据,n,m <=100000

    题解:暴力65分wdm!666(正解树链剖分)先献上暴力程序。

    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    using namespace std;
    const int N=100002;
    int x,y,n,m,vc,s;
    int a[N],l[N],r[N],c[N];
    bool op,fy[N];
    bool dfs(int u){
        if(u==x) return 1;
        if(l[u]==0 && r[u]==0) return 0;
        if(c[u]%2==0){
           if(a[x]<=a[u]) dfs(l[u]);
           else dfs(r[u]);
        }
        else{
            if(a[x]<=a[u]) dfs(r[u]);
           else dfs(l[u]);
        } 
    }
    
    void SWAP(int u){
        c[u]++;
        if(l[u]==0 && r[u]==0) return;
        SWAP(l[u]); SWAP(r[u]);
    }
    
    int main(){
        freopen("kaguya.in","r",stdin);
        freopen("kaguya.out","w",stdout);
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d %d %d",&a[i],&l[i],&r[i]); 
            fy[l[i]]=1; fy[r[i]]=1;
        }
        for(int i=1;i<=n;i++)
            if(fy[i]==0) { s=i; break; } 
        for(int i=1;i<=m;i++){
            scanf("%d",&vc);
            if(vc==1){
                scanf("%d %d",&x,&y);
                a[x]=y;
            }
            if(vc==2){
                scanf("%d",&x);
                SWAP(x);
            } 
            if(vc==3){
                scanf("%d",&x); op=dfs(s);
                if(op==0) printf("NO
    ");
                else printf("YES
    ");
            }
            //cout<<i;
        }
        return 0;
    }
  • 相关阅读:
    自学人工智能之数学篇,数学入门并不难
    2018-8-10-win10-uwp-使用资源在后台创建控件
    2019-9-2-win10-uwp-弹起键盘不隐藏界面元素
    2019-7-31-程序猿修养-日志应该如何写
    2018-11-19-WPF-在image控件用鼠标拖拽出矩形
    2019-8-31-C#-如何给-ValueTuple-返回值添加注释
    2019-11-12-浅谈-Windows-桌面端触摸架构演进
    2018-8-10-win10-uwp-打开文件管理器选择文件
    2018-8-10-win10-uwp-验证输入-自定义用户控件
    2019-8-31-dotnet-特性-DynamicallyInvokable-是用来做什么的
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11340860.html
Copyright © 2011-2022 走看看