首页 > 其他分享 >牛客小白87题解A-G

牛客小白87题解A-G

时间:2024-02-17 09:05:01浏览次数:30  
标签:int 题解 back long 牛客 vector 逆序 87 define

A小苯的石子游戏

本题贪心模拟即可

B 小苯的排序疑惑

考虑到最简单的操作把n-1个数排好,最后一个看能否有序。即:a[1]<=min(a[2],a[3],a[4]..,a[n])|| a[n]>=max(a[1],a[2],a[3]....,a[n-1])满足条件,反之易得不可能

C&D 小苯的IDE括号问题

本题考察题意理解,简单版本我们可以只关注逻辑删除,hard需要我们物理删除,所以简单版本可以用双指针扫描,最后拼接,而hard版本因为指针是线性移动无法判断是否删除,所以hard版本用vector模拟队列即可 要注意的是可能需要翻转

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
const int mod=1e9+7;
void solved()
{
     int n,k;
     cin>>n>>k;
     string s;
     cin>>s;
     vector<char> l;
     vector<char> r;
     int flag=0;
     for(int i=0;s[i];i++){
        if(s[i]=='I'){
           flag=1;
           continue;
        }
        if(flag) r.push_back(s[i]);
        else l.push_back(s[i]);
     }
     reverse(r.begin(),r.end());
     string ans;
     while(k--){
        string d;
        cin>>d;
        if(d[0]=='b'){
            if(l.empty()) continue;
            if(!r.empty()&&r.back()==')'&&l.back()=='('){
                l.pop_back();
                r.pop_back();
            }
            else l.pop_back();
        }
        else if(d[0]=='d'){
            if(r.empty()) continue;
            r.pop_back();
        }
         
        else if(d[0]=='<'){
             if(l.empty()) continue;
             r.push_back(l.back());
             l.pop_back();
        }
        else{
            if(r.empty()) continue;
            l.push_back(r.back());
            r.pop_back();
        }
        
     }
     for(auto d:l) ans+=d;
     ans+='I';
     reverse(r.begin(),r.end());
     for(auto d:r) ans+=d;
     cout<<ans<<endl;
          
 
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    while (t--)
    {
        solved();
    }
	}

E 小苯的数组构造

首先考察 如果a[i]< a[i-1] 那么我们可以把a[i]变成a[i-1]可以发现,前缀a[i]的值都会变成前缀最大值,所以b[i]=前缀最大-a[i], 考虑最大的b[i],如果极差小于b[i],可以证明无法满足单调,故,max bi为最大值.

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
const int mod=1e9+7;
void solved()
{
    int n;
    cin>>n;
    vector<int> a(n+1);
    vector<int> b(n+1);
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=2;i<=n;i++){
       if(a[i]<a[i-1]){
           b[i]=a[i-1]-a[i];
           a[i]=a[i-1];
       }
    }
    for(int i=1;i<=n;i++) cout<<b[i]<<" ";
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    while (t--)
    {
        solved();
    }
}

F 小苯的数组切分

本题考察位运算性质,首先一点 and 操作 只减不增,能维持a[n] 都算不错,所以把r固定在n,一定没有问题,考虑枚举l即可。

 #include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
const int mod=1e9+7;
void solved()
{
     int n;
     cin>>n;
     vector<int> f(n+1),g(n+1),a(n+1);
     for(int i=1;i<=n;i++) cin>>a[i];
     for(int i=n-1;i>=2;i--) f[i]=f[i+1]|a[i];
     for(int i=1;i<=n;i++) g[i]=g[i-1]^a[i];
     int ans=0;
     for(int i=1;i<=n-1;i++){
         ans=max(ans,f[i+1]+g[i]+a[n]);
     }
     cout<<ans<<endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    while (t--)
    {
        solved();
    }
}

G 小苯的逆序对

此题比较缝合考察了逆序对以及数论容斥的一些知识。考虑gcd(i,j)=x的逆序对,那么怎么求呢?
设g[x] 表示 x|gcd(i,j)的逆序对个数 那么 f[x]=g[x]-f[2x]-f[3x]-f[4x].....。 所以我们对每个x单独求,答案就是f[1].
求逆序对,我们要怎么样保证 x|gcd(i,j) 呢? 很简单,把x的倍数全部单独划分一个数组求逆序对即可,我是用值域树状数组求的,要考虑树状数组的清空,那么每次我们映射的时候就映射x的多少倍即可,这样方便清空降低时间复杂度。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
const int mod=1e9+7;
const int N=2e5+10;
int tree[N];
void updata(int idx,int k,int n){
    while(idx<=n){
        tree[idx]+=k;
        idx+=(idx)&(-idx);
    }
}
int query(int idx){
    int res=0;
    while(idx){
       res+=tree[idx];
       idx-=(idx)&(-idx);
    }
    return res;
}
void solved()
{
     int n;
     cin>>n;
     vector<int>  b(n+1);
     vector<int>  a[n+1];
     vector<int>  d[n+1];
     for(int i=1;i<=n;i++){
         cin>>b[i];
     }
     for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j+=i) a[j].push_back(i);
     }
     for(int i=1;i<=n;i++){
         for(auto &k:a[b[i]]){
            d[k].push_back(b[i]/k);
         }
     }
     auto cal=[&](int k){
         int res=0;
         //cout<<k<<":";
         for(int i=0;i<d[k].size();i++){
              //cout<<d[k][i]<<" ";
              res+=(i-query(d[k][i]));
              updata(d[k][i],1,d[k].size()+1);
         }
        // cout<<res<<endl;
         for(int i=0;i<=d[k].size()+1;i++) tree[i]=0; 
         return res;
     };
     vector<int> f(n+1);
     for(int i=n;i>=1;i--){
        f[i]=cal(i);
        for(int j=i+i;j<=n;j+=i) f[i]-=f[j];
     }
     cout<<f[1]<<endl;

}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    while (t--)
    {
        solved();
    }
}

标签:int,题解,back,long,牛客,vector,逆序,87,define
From: https://www.cnblogs.com/FinalSTian/p/18017691

相关文章

  • 0217-0224校赛部分题解
    SMUWinter2024Round#3(Div.2)对于自己比较有价值的题目是D题https://codeforces.com/gym/102897/problem/D?mobile=trueJ题https://codeforces.com/gym/102897/problem/JK题https://codeforces.com/gym/102897/problem/KE题https://codeforces.com/gym/102897/prob......
  • 关于thrift python接口和java通信出现问题解决
    真的无语,搞了一个下午。使用thrift出现错误,先说一下遇到第一个错误,如下图:那时候代码是这叼样```if__name__=='__main__':handler=MessageServiceHandler()processor=MessageService.Processor(handler)transport=TSocket.TServerSocket(None,"9090"......
  • P3157 [CQOI2011] 动态逆序对 题解
    题目链接:动态逆序对常见经典题,理解一个数对逆序对贡献计算即可。对于一个数而言,它在一个序列中的逆序对有两部分贡献,一部分为前面比它严格大的数,另一部分为后面比它严格小的数,有道二莫题也是基于此去考虑的。考虑最开始知道了总逆序数,每次删除一个数逆序数会减少两部分值,显然就......
  • 选课 题解
    题目描述大学里实行学分。每门课程都有一定的学分,学生只要选修了这门课并考核通过就能获得相应的学分。学生最后的学分是他选修的各门课的学分的总和。每个学生都要选择规定数量的课程。其中有些课程可以直接选修,有些课程需要一定的基础知识,必须在选了其它的一些课程的基础上才......
  • 牛客小白月赛87(非常菜的小白)
    这场被B坑了很长时间,导致没有看下面的题哈哈哈,还得练,赛后1分钟写出C,加训。A.小苯的石子游戏思路:Alice和Bob玩石子游戏,这里的石头谁多谁赢,不存在平局。由于本身就是升序,所以从后往前取即可。解法:由于升序,为了方便变成降序,最优解法就是最大的一个个轮流过去......
  • 洛谷 P4065 题解
    模拟赛T1,纪念一下第一次场切紫。(话说场上这么多人切是不是都找到原了,就我这么傻想了半天)正难则反,很容易的将题目转化为选择若干种颜色,使这些颜色在原数组中的位置连续。设$pre_i$为颜色$i$最早出现的位置,$suf_i$为颜色$i$最晚出现的位置。假设通过选择若干颜色得到的位......
  • P10149 [Ynoi1999] XM66F题解
    题解首先,问题是静态的区间查询问题,一眼莫队。那么我们就需要考虑所需要维护的内容在区间扩增或者缩减时的变化如何快速维护。我们可以先写出对于区间\([l,r]\)来说,满足\(l\lei<j<k\ler\)的有序三元组\((i,j,k)\)数量的表达式,方便拆式子:\[\sum\limits_{i=l}^{r}......
  • 启动vue-element-admin遇到问题解决方案
    概述从https://github.com/PanJiaChen/vue-element-admin下载代码,按照文档执行,期间遇到一些列问题。1#clonetheproject2gitclonehttps://github.com/PanJiaChen/vue-element-admin.git34#entertheprojectdirectory5cdvue-element-admin67#insta......
  • 出现8080端口占用问题解决
    查到占用端口号并关闭netstat-aon|findstr8080出现:TCP0.0.0.0:80000.0.0.0:0LISTENING23296TCP[::]:8000[::]:0LISTENING23296tasklist|findstr"23296"出现:java.exe......
  • CF739A Alyona and mex 题解
    题目简单构造,首先我们知道一个区间\([l,r]\)内的最大答案为为这个区间的长度\(len\),因为其中可以包括\([0,r-l+1]\)这些数。所以\(ans=min(len_i)\)。考虑如何满足这个条件,设最小长度为\(len_{min}\),我们可以轮流输出\([0,len_{min}]\),因为\(len_{min}\)是最小长度,所......