首页 > 其他分享 >牛客周赛 Round 38

牛客周赛 Round 38

时间:2024-03-25 17:24:34浏览次数:24  
标签:38 int ll pos 牛客 vector void ans Round

比赛链接:牛客周赛 Round 38

A:小红的正整数自增

void solve(){
    ll n;
    cin >> n;
    for(int i = 0; i <= 9; i ++){
        ll y = n + i;
        if(y % 10 == 0){
            cout << i << '\n';
            return;
        }
    }
}

B:小红的抛弃后缀

思路:9的倍数数位和也是9的倍数,模拟即可

void solve(){
    string s;
    cin >> s;
    ll sum = 0;
    for(auto c : s){
        int a = c - '0';
        sum += a;
    }
    ll sum1 = 0, ans = 0;
    for(int i = s.size() - 1; i >= 0; i --){
        if((sum - sum1) % 9 == 0) ans ++;
        int a = s[i] - '0';
        sum1 += a;
    }
    cout << ans << '\n';
}

C:小红的字符串构造

思路:因为给出的k<=n/2,所以先每两个一组,剩下的位不出现回文即可

void solve(){
    ll n, k;
    cin >> n >> k;
    for(int i = 1; i <= k; i ++){
        int u = i % 3;
        if(u == 0) cout << "aa";
        else if(u == 1) cout << "bb";
        else cout << "cc";
        n -= 2;
    }
    for(int i = 1; i <= n; i ++){
        int p = i % 22;
        char c = 'd' + p;
        cout << c;
    }
}

D:小红的平滑值插值

思路:如果没有大于等于k的间隙就制造一个,如果有等于k没有大于k的,就是0,如果有大于k的间隙就往中间插数字,使得间隙缩小,注意如果间隙是k的整数倍要-1

void solve(){
    ll n, k;
    cin >> n >> k;
    vector<ll> a(n + 1);
    for(int i = 1; i <= n; i ++) cin >> a[i];
    ll ans = 0, res = 0;
    for(int i = 2; i <= n; i ++){
        ll cha = abs(a[i] - a[i - 1]);
        if(cha > k){
            ans += cha / k;
            if(cha % k == 0) ans --;
        }
        else if(cha == k) res ++;
    }
    
    if(ans > 0) cout << ans << '\n';
    else{
        if(res == 0) cout << 1 << '\n';
        else cout << 0 << '\n';
    }
}

E:小苯的等比数列

思路:枚举起始数字和公比即可

void solve(){
    int n;
    cin >> n;
    int ans = 0;
    vector<int> a(n + 1), num(N);
    for(int i = 1; i <= n; i ++){
        cin >> a[i];
        num[a[i]] ++;
        ans = max(ans, num[a[i]]);
    }
    for(int i = 1; i < N; i ++){
        for(int j = 2; j * i < N; j ++){
            int now = i, cnt = 0;
            while(now < N && num[now]){
                now *= j;
                cnt ++;
            }
            ans = max(ans, cnt);
        }
    }
    cout << ans << '\n';
}

 F:小苯的回文询问

思路:记录每一个数字的上一个出现的地址,用一个map来记录每个数字出现的地址,映射到b来先处理出每个数字上次出现的位置,然后再从后往前看有没有相邻出现的情况,如果有就让b[i] = b[b[i]],这样就映射到了这个数字的相邻位置的前一个的位置,最后维护一下区间最值,只要区间最值大于等于L即可,区间最值实现方法多种

struct ST{
    int n, q;
    vector<vector<int>> f;
    ST(int _n) : n(_n), f(25, vector<int>(n + 1, 0)) {}
    void init(vector<int> & a){
        for(int i = 1; i <= n; i ++) f[0][i] = a[i];
        for(int j = 1; j <= 20; j ++){
            for(int i = 1; i + (1 << j) - 1 <= n; i ++){
                f[j][i] = max(f[j - 1][i], f[j - 1][i + (1ll << (j - 1))]);
            }
        }
    }
    int query(int l, int r){
        int len = __lg(r - l + 1);
        return max(f[len][l], f[len][r - (1 << len) + 1]);
    }
};
void solve(){
    int n, q;
    cin >> n >> q;
    vector<int> a(n + 1), b(n + 1);
    for(int i = 1; i <= n; i ++) cin >> a[i];
    map<int, int> la;
    for(int i = 1; i <= n; i ++){
        if(la.count(a[i])){
            b[i] = la[a[i]];
        }
        la[a[i]] = i;
    }
    for(int i = n; i >= 1; i --){
        if(b[i] == i - 1){
            b[i] = b[b[i]];
        }
    }
//    for(int i = 1; i <= n; i ++) cout << b[i] << ' ';
    ST st(n);
    st.init(b);
    while(q --){
        ll l, r;
        cin >> l >> r;
        ll ans = st.query(l, r);
        if(ans >= l) cout << "YES\n";
        else cout << "NO\n";
    }
}

G:小红的区间删除

思路:先思考逆序对的一种计算方法:一个数能过组成的逆序对就是它前面大于它的数字和它后面小于它的数字的数量之和

所以我们用维护两个东西:前缀和后缀

这里用滑动窗口来维护到 i 的一个最大的删除后满足性质的区间,每次加上这个区间的长度,原因是可以发现,窗口的前缀以及中间的都会随着窗口的改变被计算过,所以只需要计算一个后缀的区间即可

每次删除一个元素的时候要注意删去它在后缀中小于这个数字的贡献,再删去前缀中大于这个数字的贡献

当释放滑动窗口内的元素,加上这个元素前缀中的贡献和后缀中的贡献

特殊的,当整个数组的逆序数本身满足大于等于k,不要忘记加上

struct BIT{
    int n;
    vector<int> tr;
    BIT(int _n) : n(_n), tr(n + 10) {}
    int lowbit(int x) {return x & (- x);};
    void add(int x, int y){
        for(int pos = x; pos < n; pos += lowbit(pos)){
            tr[pos] += y;
        }
    }
    ll query(ll x){
        ll res = 0;
        for(int pos = x; pos; pos -= lowbit(pos)){
            res += tr[pos];
        }
        return res;
    }
    ll query(ll l, ll r){
        return query(r) - query(l - 1);
    }
};
void solve(){
    int n, k;
    cin >> n >> k;
    vector<ll> a(n + 1);
    for(int i = 1; i <= n; i ++) cin >> a[i];
    BIT bit1(1e6 + 10);//维护后缀 
    BIT bit2(1e6 + 10);//维护前缀 
    ll sum = 0;
    for(int i = n; i >= 1; i --){
        bit1.add(a[i], 1);
        sum += bit1.query(a[i] - 1);
    }//处理逆序对和后缀 
    
    int ans = (sum >= k);
    for(int i = 1, j = 1; i <= n; i ++){
        bit1.add(a[i], -1);//删掉ai 
        sum -= bit1.query(a[i] - 1);//从后缀中删掉比ai小的 
        sum -= bit2.query(a[i] + 1, 1e6);//从前缀中删掉(所有的-小于等于ai)即删去前缀中大于ai的 
//        cout << sum << '\n';
        while(j <= i && sum < k){//小于,就要把aj补回来,注意是补入前缀数组 
            bit2.add(a[j], 1);
            sum += bit1.query(a[j] - 1);
            sum += bit2.query(a[j] + 1, 1e6);
            j ++;
        }
        ans += (i - j + 1);
//        cout << i << ' ' << j << '\n'; 
    }
    cout << ans << '\n';
}

 

标签:38,int,ll,pos,牛客,vector,void,ans,Round
From: https://www.cnblogs.com/RosmontisL/p/18094005

相关文章

  • 每日一练:LeeCode-38、外观数列【字符串】
    给定一个正整数n,输出外观数列的第n项。「外观数列」是一个整数序列,从数字1开始,序列中的每一项都是对前一项的描述。你可以将其视作是由递归公式定义的数字字符串序列:countAndSay(1)="1"countAndSay(n)是对countAndSay(n-1)的描述,然后转换成另一个数字字符串。......
  • 牛客小白月赛
     B-显生之宙_牛客小白月赛89(nowcoder.com)题解:思路很简单,但是当时晕晕的,写拉了题目要求最大,那么负数要让每一个数都加,正数只能加一个我们正数加到最后一个数即可,负数累加#include<bits/stdc++.h>//#pragmaGCCoptimize("Ofast")#include<iostream>#include<cstdio......
  • cfEduRound163div2--D题解
    D-TandemRepeats?题意:做法:因为字符串长度较少,可以考虑枚举。or--动态规划voidsolve(){//D枚举//枚举!!!!!!!!!!stringstr;cin>>str;intn=str.size(),ans=0;for(inti=1;i<=n/2;i++){//枚举一半!!!intcnt=0;for(intj=0;......
  • 牛客--2024中国传媒大学程序设计大赛(同步赛)
    A-小苯的区间和疑惑题意:做法:前缀最大值+后缀最大值 or 线段树维护最大子段和intarr[200005],pre[200005],last[200005];voidsolve(){//小笨的区间和疑惑--前缀最大值+后缀最大值or线段树维护最大自段和intn;cin>>n;for(inti=1;i<=n;i++)cin......
  • Programming Abstractions in C阅读笔记:p338-p346
    《ProgrammingAbstractionsinC》学习第80天,p338-p346,总计9页。一、技术总结栈的实现包括入栈、出栈、判断栈是否为满,判断栈是否为空等。作者结合RPN计算器来实现,稍显无聊。/**File:rpncalc.c*---------------*Thisprogramsimulatesanelectroniccalculatorth......
  • 牛客周赛ROUND37--C题解
    C-红魔馆的馆主(495倍数)题意:做法:dfs搜索后面添加的数字。stringans="1000000000000000000";voiddfs(intcur,stringaddnum){//用数字写的话会无限dfs,因为addnum永远等于0。if(cur==0){if(addnum.size()<ans.size())ans=addnum;return;......
  • C# 异步控件 backgroundWorker
    //.net4.8WinformusingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;usingSystem.Threading......
  • Maximum Sum(Round 936)
    #include<bits/stdc++.h>#defineendl'\n'usingll=longlong;typedefunsignedlonglongull;usingnamespacestd;voidGordenGhost();constllmod=1e9+7;llmaxSum(vector<ll>a,intw){llsum=0;llb=0;for(inti......
  • 牛客周赛32——小红的矩阵修改
     题目:小红的矩阵修改状态压缩dp,对于每一个串,我们使用一个三进制数表示,由于只有三种字符,我们使用3进制数表示,这样一共就只有81中状态。#include<bits/stdc++.h>typedeflonglongll;usingnamespacestd;constintN=5e2+10;constintmod=1e9+7;intdp[1010]......
  • Codeforces Round 936 (Div. 2) D
    AB没什么好说的C二分答案,写的还是不够快,但是也很好了。D的问题有点大。我好像一直有一个不对的贪心再用,对于二进制的。就是我会觉得一堆树或起来小于一个数字,这种限制是每个数字都小于那个数字就可以了。但是实际上这就是一个很明显错误的贪心。然后另一个反映就是,对于二进......