牛客小白月赛109 【题解待补】

60 阅读2分钟
题目难度知识点
A Onewan的疑惑签到
B 菲菲姐的游戏思维
C 猪猪养成计划1set/模拟/并查集
D 猪猪养成计划2★★线性DP

image.png 最无语的一场,A题再瞎搞心态崩了。

Onewan的疑惑

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int main(void)
{
    LL n; cin>>n;
    LL l=max(n-5201314-14174017,1ll);
    LL r=n;
    cout<<r-l+1;
    return 0;
}

菲菲姐的游戏

每个人的最优都是只选一个,且选最大的数。 故前后缀,枚举即可。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5*2+10;
typedef long long int LL;
LL a[N],n,k1,k2;
LL l[N],r[N];
int main(void)
{
    cin>>n>>k1>>k2;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) l[i]=max(l[i-1],a[i]);
    for(int i=n;i>=1;i--) r[i]=max(r[i+1],a[i]);
    int flag=0;
    for(int i=1;i<=n-1;i++)
    {
        if(l[i]>r[i+1]) flag=1;
    }
    if(flag) puts("Yes");
    else puts("No");
    return 0;
}

猪猪养成计划1

image.png 模拟,因为未标记的数量会越来越少。

#include<bits/stdc++.h>
using namespace std;
deque<int>q,temp;
map<int,int>mp;
int n,m,cnt;
int main(void)
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) q.push_back(i);
    while(m--)
    {
        int op; cin>>op;
        if(op==1)
        {
            int l,r; cin>>l>>r;
            temp.clear();
            while(q.size())
            {
                while(q.front()<l) temp.push_back(q.front()),q.pop_front();
                if(q.size()&&q.front()>=l&&q.front()<=r) mp[q.front()]=++cnt,q.pop_front();
                if(q.size()&&q.front()>r) break;
            }
            while(q.size()) temp.push_back(q.front()),q.pop_front();
            q=temp;
        }else
        {
            int x; cin>>x;
            cout<<mp[x]<<'\n';
        }
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int p[N],ans[N],n,q,cnt;//p[i]是以i为左端点,最右端点的下一个
int find(int x)
{
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}
void merge(int a,int b)
{
    int fa=find(a),fb(find(b));
    if(fa>fb) swap(fa,fb); 
    p[fa]=fb;
}
int main(void)
{
    cin>>n>>q;
    for(int i=1;i<=n+1;i++) p[i]=i;
    //n+1是一个哨兵,避免死循环
    while(q--)
    {
        int op; cin>>op;
        if(op==1)
        {
            int l,r; cin>>l>>r;
            for(int i=l;i<=r;i=find(i))
            {
                if(ans[i]==0) ans[i]=++cnt;
                merge(i,i+1);
            }
        }else 
        {
            int x; cin>>x;
            cout<<ans[x]<<'\n';
        }
    }
    return  0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,q,ans[N],cnt;
set<int>st;
int main(void)
{
    cin>>n>>q;
    for(int i=1;i<=n;i++) st.insert(i);
    while(q--)
    {
        int op; cin>>op;
        if(op==1)
        {
            int l,r; cin>>l>>r;
            auto it=st.lower_bound(l);
            while(it!=st.end() && *it<=r )
            {
                ans[*it]=++cnt;
                it=st.erase(it);
            }
        }else{
            int x; cin>>x;
            cout<<ans[x]<<'\n';
        }
    }
    return 0;
}

猪猪养成计划2

image.png dp[i]表示前i天都陪伴好的最小的变化值。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long int LL;
LL a[N],b[N],val[N];
LL n,m,dp[N],sum;
int main(void)
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        cin>>b[i]>>val[i];
        sum+=val[i];  
    }
    vector< vector<pair<int,int>> > ve(n+2);
    for(int i=1;i<=n;i++) ve[a[i]].push_back({b[i],val[i]});
    memset(dp,0x3f,sizeof dp);
    dp[0]=0;
    for(int i=0;i<=n;i++)
    {
        for(int j=0;j<ve[i].size();j++)
        {
            dp[i+m]=min(dp[i+m],dp[i]+ve[i][j].first-ve[i][j].second);//陪伴
        }  
        dp[i+1]=min(dp[i],dp[i+1]);//第i天这个猪不陪伴
    }
    cout<<sum+dp[n];
    return 0;
}