牛客练习赛85 A~D题题解

Posted kaka0010

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客练习赛85 A~D题题解相关的知识,希望对你有一定的参考价值。

比赛链接:https://ac.nowcoder.com/acm/contest/11175

A 科学家的模型

模拟题,对每行数字和排序,最小值是1的肯定是9。

除去9之后,如果第3大和第4大相等,那么一定是8

之后全是0

#include <bits/stdc++.h>
using namespace std;
char mp[5][5];
int num[5];
int main() {
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            cin >> mp[i][j];
            num[i] += mp[i][j] - '0';     
        }
    }
    sort(num, num + 5);
    if (num[0] == 1) cout << 9 << endl;
    else if (num[2] == num[3]) cout << 8 << endl;
    else cout << 0 << endl;
}

B 音乐家的曲调

考虑DP

我们找每个点可以到达的最前面那个点,然后列出方程转移一下。
f [ i ] [ 3 ] = m a x ( f [ i − 1 ] [ 3 ] , f [ p r e − 1 ] [ 2 ] + ( i − p r e + 1 ) ) f[i][3]=max(f[i-1][3],f[pre-1][2]+(i-pre+1)) f[i][3]=max(f[i1][3],f[pre1][2]+(ipre+1))

f [ i ] [ 2 ] = m a x ( f [ i − 1 ] [ 2 ] , f [ p r e − 1 ] [ 2 ] + ( i − p r e + 1 ) ) f[i][2]=max(f[i-1][2],f[pre-1][2]+(i-pre+1)) f[i][2]=max(f[i1][2],f[pre1][2]+(ipre+1))

f [ i ] [ 1 ] = m a x ( f [ i − 1 ] [ 1 ] , f [ p r e − 1 ] [ 2 ] + ( i − p r e + 1 ) ) f[i][1]=max(f[i-1][1],f[pre-1][2]+(i-pre+1)) f[i][1]=max(f[i1][1],f[pre1][2]+(ipre+1))

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e7 + 10;
const int MOD = 1e9 + 7;
char s[N];
int pre[N], lmax[N];
int dp[N][4];
queue<int> que[26];
void solve () {
    int n, m; cin >> n >> m;
    cin >> (s + 1);
    lmax[0] = 1;
    for (int i = 1; i <= n; i++) {
        que[s[i]-'a'].push(i);
        lmax[i] = max(lmax[i], lmax[i-1]);
        if (que[s[i]-'a'].size() > m) {
            int now = que[s[i]-'a'].front();
            que[s[i]-'a'].pop();
            pre[i] = now;
            lmax[i] = max(lmax[i], pre[i] + 1);
        }
    }
    //for (int i = 1; i <= n; i++) cout << lmax[i] << endl;
    for (int i = 1; i <= n ;i++) {
        dp[i][3] = max(dp[i-1][3], dp[lmax[i] - 1][2] + (i - lmax[i] + 1));
        dp[i][2] = max(dp[i-1][2], dp[lmax[i] - 1][1] + (i - lmax[i] + 1));
        dp[i][1] = max(dp[i-1][1], dp[lmax[i] - 1][0] + (i - lmax[i] + 1));
    }
    cout << dp[n][3] << endl;
}
signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("input", "r", stdin);
    freopen("output", "w", stdout);
#endif
    solve();
    return 0;
}


C 哲学家的沉思

转化一下题意变成找每个数后第一个大于它的数。

然后用nxt数组串起来,倍增处理一下之后暴力跳就可以了。

f [ i ] [ j ] = f [ f [ i ] [ j − 1 ] ] [ j − 1 ] f[i][j]=f[f[i][j-1]][j-1] f[i][j]=f[f[i][j1]][j1]

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e7 + 10;
const int MOD = 1e9 + 7;
int r[N], a[N], stk[N], top;
int f[N][21];
void solve () {
    int n, m; cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> a[i];
    a[n+1] = INF;
    for (int i = 1; i <= n + 1; i++) {
        while (top && a[i] > a[stk[top]]) r[stk[top]] = i, f[stk[top]][0] = i, top--;
        stk[++top] = i;
    }
    for (int i = 0; i <= 20; i++) f[n][i] = f[n+1][i] = n + 1;
    for (int j = 1; j <= 20; j++) {
        for (int i = 1; i <= n; i++) {
            f[i][j] = f[f[i][j-1]][j-1];
        }
    }
    for (int i = 1; i <= m; i++) {
        int L, R; cin >> L >> R;
        int now = L, ans = 0;
        for (int j = 20; ~j; j--) {
            if (f[now][j] <= R) {
                ans += (1 << j);
                now = f[now][j];
            }
        }
        cout << ans + 1 << endl;
    }
}
signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("input", "r", stdin);
    freopen("output", "w", stdout);
#endif
    solve();
    return 0;
}


D 数学家的迷题

查询区间积后素因子的个数。

本来最早的想法是主席树,但有修改就显得很麻烦了,瞄了一眼题解发现了bitset,马上就懂了。

我们只要把pushup中的bitset进行或运算即可,质因数分解常数太大还tle好多次。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
const int MOD = 1e9 + 7;
int prime[N], cnt, tot, a[N];
bool is_prime[N];
unordered_map<int, int> mp;
void get_prime(){
    memset(is_prime, true, sizeof is_prime);
    is_prime[0] = is_prime[1] = false;
    for(int i = 2 ; i < N;i++){
        if (is_prime[i]) prime[++cnt] = i;
        for(int j = 1; j <= cnt && 1ll * i * prime[j] < N;j++){
            is_prime[i * prime[j]] = false;
            if(i % prime[j] == 0) break;
        }
    }
}
struct node {
    int l, r;
    bitset<10005> bi;
}t[50005 << 2];

void push_up(int u) {
    t[u].bi = t[u<<1].bi | t[u<<1|1].bi;
}
void build(int u, int l, int r) {
    t[u].l = l, t[u].r = r;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(u<<1, l, mid);
    build(u<<1|1, mid+1, r);
}
void add(int u, int pos, int y) {
    if (t[u].l == t[u].r) {
        t[u].bi.set(y);
        return;
    }
    int mid = (t[u].l + t[u].r) >> 1;
    if (pos <= mid) add(u<<1, pos, y);
    else add(u<<1|1, pos, y);
    push_up(u);
}
void reset(int u, int pos) {
    if (t[u].l == t牛客练习赛82总结+题解(只有A题Mocha 的字符串)

牛客练习赛83题解

牛客练习赛D数学家的谜题线段树+bitset优化

牛客练习赛85 F.音游家的谱面(Hard version)(dp的多种优化)

牛客练习赛85 D.数学家的迷题(bitset暴力)

牛客网练习赛7-D-无向图(bfs,链式前向星)