[hihocoder][Offer收割]编程练习赛60

时间:2023-02-14 12:25:25

hohahola

[hihocoder][Offer收割]编程练习赛60[hihocoder][Offer收割]编程练习赛60
#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    lint n, x, y, z;
    cin >> n >> x >> y >> z;
    if (z >= y) cout << (n * z / x) << endl;
    else {
        lint l = 0, r = n, mid;
        lint ans = 0;
        while (l + 1 < r) {
            mid = (l + r) / 2;
            if ((n - mid) * z >= (x - y) * mid) {
                l = mid;
                ans = max(ans, mid);
            } else r = mid;
        }
        cout << ans << endl;
    }
    return 0;
}
View Code

最大顺子

要使顺子的值最大,m张任意牌肯定全用完了,因为任意牌可以放在有数字的牌的右边

[hihocoder][Offer收割]编程练习赛60[hihocoder][Offer收割]编程练习赛60
#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

lint a[110000], f[110000], s[110000];

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 0; i < n; i++) cin >> a[i];
    sort(a, a + n);
    lint ans = 0;
    int p = k - m;
    for (int i = 0; i + p - 1 < n; i++) {
        int j = i + p - 1;
        if (a[j] - a[i] + 1 - p <= m) ans = max(ans, a[i] + k - 1);
    }
    cout << ans << endl;
    return 0;
}
View Code

路径包含问题

[hihocoder][Offer收割]编程练习赛60[hihocoder][Offer收割]编程练习赛60
#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

class LCA {
public:
    int n;
    int ancient[110000][20], depth[110000], father[110000], sz[110000];
    vector<vector<int>> * T;
    void init(vector<vector<int>> *, int, int);
    void dfs(int, int, int);
    int query(int, int);
};
void LCA::dfs(int root, int fa, int dep) {
    ancient[root][0] = fa;
    depth[root] = dep;
    sz[root] = 1;
    for (int i = 0; i < (*T)[root].size(); i++) {
        int u = (*T)[root][i];
        if (u == fa) continue;
        dfs(u, root, dep + 1);
        sz[root] += sz[u];
    }
}
void LCA::init(vector<vector<int>> * G, int root, int nn) {
    T = G, n = nn;
    dfs(root, -1, 0);
    for (int i = 0; i < 20; i++) ancient[root][i] = -1;
    for (int i = 1; i < 20; i++) {
        for (int j = 1; j <= n; j++) {
            if (ancient[j][i - 1] == -1) ancient[j][i] = -1;
            else ancient[j][i] = ancient[ancient[j][i - 1]][i - 1];
        }
    }
}
int LCA::query(int u, int v) {
    if (depth[u] > depth[v]) swap(u, v);
    int d = 0;
    while (depth[u] != depth[v]) {
        if ((depth[v] - depth[u]) & (1 << d)) v = ancient[v][d];
        d++;
    }
    if (u == v) return u;
    for (int i = 19; i >= 0; i--) {
        if (ancient[u][i] != ancient[v][i]) u = ancient[u][i], v = ancient[v][i];
    }
    return ancient[u][0];
}

LCA lca;
vector<vector<int>> G(110000, vector<int>());;
int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    int n, m, u, v;
    cin >> n >> m;
    for (int i = 1; i < n; i++) {
        cin >> u >> v;
        G[u].push_back(v);
    }
    lca.init(&G, 1, n);
    for (int i = 0; i < m; i++) {
        cin >> u >> v;
        if (lca.depth[u] > lca.depth[v]) swap(u, v);
        int w = lca.query(u, v), vv = v;
        if (w == u) {
            int d = 0;
            while (lca.depth[u] != lca.depth[vv] - 1) {
                if ((lca.depth[vv] - 1 - lca.depth[u]) & (1 << d)) vv = lca.ancient[vv][d];
                d++;
            }
            cout << (1LL * (n - lca.sz[vv])*lca.sz[v]) << endl;
        } else cout << (1LL * lca.sz[u] * lca.sz[v]) << endl;
    }
    return 0;
}
View Code

 树上的节点cd之间有两种关系,其中一个是另一个的祖先,或两者都不是对方的祖先,判断两者的关系,把路径两端的点的数量相乘

随机排列

枚举左边界

[hihocoder][Offer收割]编程练习赛60[hihocoder][Offer收割]编程练习赛60
#pragma comment(linker, "/STACK:102400000,102400000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<functional>
#include<math.h>
//#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef queue<int> QI;

void makedata() {
    freopen("input.txt", "w", stdout);
    fclose(stdout);
}

lint ans[110000];
int a[110000], m[110000][20], M[110000][20], LOG2[110000];

void init(int n) {
    for (int i = 2; i <= n; i++) LOG2[i] = LOG2[i >> 1] + 1;
    for (int i = 1; i <= n; i++) m[i][0] = M[i][0] = a[i];
    for (int j = 1; (1 << j) <= n; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
            m[i][j] = min(m[i][j - 1], m[i + (1 << (j - 1))][j - 1]);
            M[i][j] = max(M[i][j - 1], M[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int query(int l, int r) {
    int k = LOG2[r - l + 1];
    return max(M[l][k], M[r - (1 << k) + 1][k]) - min(m[l][k], m[r - (1 << k) + 1][k]);
}

VI R, C;

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif
    //makedata();
    std::ios::sync_with_stdio(0), cin.tie(0);
    int n, t;
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> a[i];
        memset(ans, 0, sizeof(ans));
        init(n);
        R.clear();
        for (int i = n; i >= 1; i--) {
            C = R;
            R.clear();
            R.push_back(i);
            for (int j = 0; j < C.size(); j++) {
                if (query(i, R[R.size() - 1]) != query(i, C[j])) R.push_back(C[j]);
            }
            for (int j = 0; j < R.size() - 1; j++) ans[query(i, R[j])] += R[j + 1] - R[j];
            ans[query(i, R[R.size() - 1])] += n - R[R.size() - 1] + 1;
        }
        for (int i = 0; i < n; i++) {
            cout << ans[i] << endl;
            ans[i + 1] += ans[i];
        }
    }
    return 0;
}
View Code