• 2019百度之星复赛的几道题


    Quasi Binary Search Tree

    贪心,重构二叉树,

    1.如果左右子树最小节点都比当前节点大,则选择节点数少的子树当作左子树。节点数一样执行2

    2.如果左子树最小节点比右子树最小节点大,则交换左右子树。

    重构完成后中序遍历,标号

    //
    // Created by liulex on 2020/7/24.
    //
    #include <bits/stdc++.h>
    
    using namespace std;
    #define int long long
    signed L[100005],R[100005];
    bool vis[100005];
    signed n;
    signed lsz[100005],rsz[100005];
    signed mi[100005],f[100005],A[100005];
    
    signed dfs(signed x)
    {
        mi[x] = 1e9;
        if(L[x]){
            mi[x] = min(mi[x],dfs(L[x]));
            f[x] = -1;
            lsz[x] = lsz[L[x]]+1;
        }
        if(R[x]){
            signed k = dfs(R[x]);
    
            if(k < mi[x]){
                f[x] = 1;
                mi[x] = k;
            }
            rsz[x] = rsz[R[x]] + 1;
        }
        return min(mi[x],x);
    }
    void build(signed x)
    {
        if(mi[x] > x){
            if(lsz[x] > rsz[x]){
                swap(L[x],R[x]);
            }
        }else{
            if(f[x] == 1){
                swap(L[x],R[x]);
            }
        }
        if(L[x]){
        build(L[x]);}
        if(R[x]){
        build(R[x]);}
    }
    int cnt = 0;
    void traver(int x){
        if(L[x]){
        traver(L[x]);
        }
        A[cnt++] = x;
        if(R[x]) {
            traver(R[x]);
        }
    }
    int mod = 1e9 + 7;
    int F[100005];
    void init()
    {
        F[0] = 1;
        for(int i = 1; i <= 100000; i++){
            F[i] = (F[i-1]*233ll)%mod;
        }
    }
    signed main()
    {
        signed T;
        init();
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            for(int i = 1; i <= n; i++){
                scanf("%d%d",&L[i],&R[i]);
                vis[L[i]] = true;
                vis[R[i]] = true;
            }
            signed root = -1;
            for(int i = 1; i <= n; i++){
                if(!vis[i]){
                    root = i;
                }else{
                    vis[i] = false;
                }
            }
            dfs(root);
            build(root);
            cnt = 1;
            traver(root);
            int ans = 0;
            for(int i = 1; i <= n; i++){
                ans = (ans +(i^A[i])*F[A[i]]%mod)%mod;
            }
            cout<< ans <<
            '
    ';
            for(int i = 1; i <= n; i++){
                lsz[i] = rsz[i] = mi[i] = f[i] = A[i] = 0;
            }
    
        }
    }

    Diversity

    树形dp,dp[x][0]表示当前节点取L[x],dp[x][1]表示当前节点取R[x]

    #include <bits/stdc++.h>
    using namespace std;
    vector<int> G[100005];
    int L[100005],R[100005];
    long long dp[100005][2];
    int n,x,y;
    void dfs(int x,int f)
    {
        dp[x][0] = dp[x][1] = 0;
        for(auto i : G[x]){
            if(i != f){
                dfs(i,x);
                dp[x][0] += max(abs(L[x]-L[i])+dp[i][0],abs(L[x]-R[i])+dp[i][1]);
                dp[x][1] += max(abs(R[x]-L[i])+dp[i][0],abs(R[x]-R[i])+dp[i][1]);
            }
        }
    }
    int main() {
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&n);
            for(int i = 0; i < n - 1; i++){
                scanf("%d%d",&x,&y);
                G[x].push_back(y);
            }
            for(int i = 1; i <= n; i++){
                scanf("%d%d",&L[i],&R[i]);
            }
            dfs(1,-1);
            cout<<max(dp[1][0],dp[1][1])<<'
    ';
            for(int i= 1;i <= n; i++){
                G[i].clear();
            }
        }
        return 0;
    }

    Transformation

    打表找规律

    //
    // Created by liulex on 2020/7/24.
    //
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    int P[70];
    void init()
    {
        P[0] = 1;
        for(int i = 1; i <= 62; i ++) {
            P[i] = (P[i - 1] * 2ll);
        }
    }
    int a,b,c,d;
    signed main()
    {
        init();
        int T;
        scanf("%lld",&T);
        while(T--){
            scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
            if(a == b && (c != a ||d != b)){
                puts("No");
            }else if(a == c && b == d){
                puts("Yes");
                cout<<'
    ';
            }else if((c + d) &1){
                puts("No");
            }else if(a > b && (c < a || d > b)){
                puts("No");
            }else if(a < b && (d < b || c > a)){
                puts("No");
            }else{
                int r = abs(a - b);
                int k = abs(c - a);
    
                if(k%r != 0){
                    puts("No");
                }else{
    
                    k = k/r;
                    string s = "";
    
                    if(k == 0){
    
                    }else if(k == 1){
                    s = 'B';
                    }else{
                    int i = 0;
                    while(k > P[i]){
                        k -= P[i];
                        i++;
                    }
                    s = 'B';
                    while(i > 0) {
                        if (k <= P[i] / 2) {
                             s = 'A'+s;
                        }else {
                            k -= P[i]/2;
                            s = 'B' + s;
                        }
                        i--;
                    }
    
    
                    }
    
                    bool flag = (a > b);
    
                    for(auto& i: s){
                        if(i == 'A'){
                            b = 2*b - a;
                        }else{
                            a = 2*a - b;
                        }
                    }
                    if(flag && b < d){
                        puts("No");
                    }else if((!flag) && b > d){
                        puts("No");
                    }else{
    
                        int u = b-a;
                        int o = b;
                        for(int i=0;i<62;i++){
    
                            if(((u > 0) && (P[i] - 1) * u + o > d)||(u < 0 &&(P[i] - 1) * u + o < d)){
                                puts("No");
                                break;
                            }else if((P[i] - 1) * u + o == d){
    
                                for(int j = 0; j < i ; j ++){
                                    s += 'A';
                                }
                                puts("Yes");
                                cout<<s<<'
    ';
                                break;
                            }
                        }
                    }
    
    
                }
            }
        }
    }
  • 相关阅读:
    MFC自绘框架窗口客户区
    命令行下创建mysql数据库
    linux重置mysql root密码的6种方
    xampp修改mysql默认密码详解
    Java常用包装类
    Java异常处理
    Java数组
    Java流程控制
    Java基本数据类型
    golang https server分析
  • 原文地址:https://www.cnblogs.com/liulex/p/13375849.html
Copyright © 2020-2023  润新知