Educational Codeforces Round 97 (Rated for Div. 2)

2020-10-29

补了一场Edu round。

A : Marketing Scheme

水题

#include <cstdio>
#include <algorithm>
typedef long long ll;
int T,l,r;

template <typename T>
inline void read(T &x){
    x = 0; char ch = getchar(); int f = 1;
    for(;ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
    for(;ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    x *= f;
}
int main(){
    read(T);
    while(T--){
        read(l); read(r);
        if(l * 2 > r) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

B :Reverse Binary Strings

水构造

#include <cstdio>
#include <algorithm>
typedef long long ll;
const int M = 200010;
int T,n,cnt1,cnt2;
int a[M];

template <typename T>
inline void read(T &x){
    x = 0; char ch = getchar(); int f = 1;
    for(;ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
    for(;ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    x *= f;
}
int main(){
    read(T);
    while(T--){
        read(n); cnt1 = cnt2 = 0;
        for(int i = 1;i <= n; i++){
            char ch = getchar();
            for(;ch != '0' && ch != '1'; ch = getchar()) ;
            a[i] = ch - '0';
            if(i != 1){
                if(a[i] == a[i - 1] && a[i] == 1) cnt1++;
                else if(a[i] == a[i - 1] && a[i] == 0) cnt2++;
            }
        }
        printf("%d\n",std::max(cnt1,cnt2));
    }
    return 0;
}

C : Chef Monocarp

比较奇怪的背包,照理压成一维。

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
typedef long long ll;
const int M = 210;
int T,n;
int t[M], dp[M];

template <typename T>
inline void read(T &x){
    x = 0; char ch = getchar(); int f = 1;
    for(;ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
    for(;ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    x *= f;
}
int main(){
    read(T);
    while(T--){
        read(n);
        for(int i = 1;i <= n; i++) read(t[i]);
        std::sort(t + 1,t + n + 1);
        memset(dp,0x3f,sizeof(dp));
        dp[0] = 0;
        for(int i = 1;i <= n << 1; i++)
            for(int j = n;j >= 1; j--)
                dp[j] = std::min(dp[j],dp[j - 1] + abs(i - t[j]));
        printf("%d\n",dp[n]);
    }
    return 0;
}

D :Minimal Height Tree

因为是bfs,所以直接按照性质模拟即可。

#include <cstdio>
#include <algorithm>
typedef long long ll;
const int M = 200010;
int T,n;
int a[M];

template <typename T>
inline void read(T &x){
    x = 0; char ch = getchar(); int f = 1;
    for(;ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
    for(;ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    x *= f;
}
int main(){
    read(T);
    while(T--){
        read(n);
        for(int i = 1;i <= n; i++) read(a[i]);
        int dep = 0, cur = 0, sum = 1;
        for(int i = 2,j;i <= n; i++){
            if(!cur){
                cur = sum; dep++;
            }
            cur--; j = i;
            while(j <= n){
                if(a[j] < a[j + 1]){
                    j++; sum++;
                }
                else break;
            }
            i = j;
        }
        printf("%d\n",dep);
    }
    return 0;
}

E :Make It Increasing

贪心。直接在每个被b圈定的区间内贪心,记录不需要更改的点个数。

还有一个明显的转化,具体见代码。

#include <cstdio>
#include <algorithm>
typedef long long ll;
const int M = 500010;
int n,k,ans;
int a[M], b[M];

template <typename T>
inline void read(T &x){
    x = 0; char ch = getchar(); int f = 1;
    for(;ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
    for(;ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    x *= f;
}
int sta[M], top = 0;
int main(){
    read(n); read(k);
    for(int i = 1;i <= n; i++)
        read(a[i]), a[i] -= i;
    for(int i = 1;i <= k; i++) read(b[i]);
    a[n + 1] = 1e9; a[0] = -1e9;
    b[k + 1] = n + 1;
    for(int i = 0,l,r;i <= k; i++){
        l = b[i]; r = b[i + 1];
        if(a[l] > a[r]){
            printf("-1\n"); return 0;
        }
        top = 0;
        for(int j = l + 1;j < r; j++)
            if(a[l] <= a[j] && a[j] <= a[r]){
                int it = std::upper_bound(sta + 1,sta + top + 1,a[j]) - sta;
                if(it == top + 1) sta[++top] = a[j];
                else sta[it] = a[j];
            }
        ans += r - l - 1 - top;
    }
    printf("%d\n",ans);
    return 0;
}

F :Emotional Fishermen

既然是记录方案数,那应该是dp了。具体见代码,注意特判。

#include <cstdio>
#include <algorithm>
typedef long long ll;
const int M = 5010, mod = 998244353;
int n;
int a[M], pre[M];//表示最大的j使得a[j] * 2 <= a[i]
int dp[M];//表示以i点为最大值的方案数

template <typename T>
inline void read(T &x){
    x = 0; char ch = getchar(); int f = 1;
    for(;ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
    for(;ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
    x *= f;
}
inline ll q_pow(ll x,ll num){
    ll ret = 1;
    for(;num; num >>= 1){
        if(num & 1) ret = (1ll * ret * x) % mod;
        x = (1ll * x * x) % mod;
    }
    return ret;
}
int fac[M], ifac[M];
inline void pre_work(){
    fac[0] =  fac[1] = ifac[0] = 1;
    for(int i = 2;i <= n; i++) fac[i] = (1ll * fac[i - 1] * i) % mod;
    ifac[n] = q_pow(fac[n],mod - 2);
    for(int i = n - 1;i >= 1; i--) ifac[i] = (1ll * ifac[i + 1] * (i + 1)) % mod;
}
inline int A(int i,int j){
    if(i > j || i < 0 || j < 0) return 0;
    return (1ll * fac[j] * ifac[j - i]) % mod;
}
int main(){
    read(n);
    for(int i = 1;i <= n; i++) read(a[i]);
    std::sort(a + 1,a + n + 1);
    int l = 0;
    for(int i = 1;i <= n; i++){
        while(a[l + 1] << 1 <= a[i]) l++;
        pre[i] = l;
    }
    if(pre[n] != n - 1){
        printf("0\n"); return 0;
    }
    dp[0] = 1; pre[0] = -1;
    pre_work();
    for(int i = 1;i <= n; i++)
        for(int j = 0;j <= pre[i]; j++)
            dp[i] = (1ll * dp[i] + 1ll * dp[j] * A(pre[i] - pre[j] - 1,n - pre[j] - 2) % mod) % mod;
    printf("%d\n",dp[n]);
    return 0;
}

G :Death DBMS

后缀自动机,不会。