牛客周赛 Round 88【题解完成】

题目 难度 知识点
A 吔我大炮! 签到
B 梦间 签到
C 坠入 签到
D 漫步 ★★ 思维
E 秘藏 ★★ 简单DP
F 回响 ★★★ 构造,贪心
G 升!龙! ★★ dfs序 简单树形DP 树上前缀

F,G。F构造了半天没搞出来,G直接放弃了,其实就是用dfs序将其树上问题转区间问题,不过这玩意几年没碰了算是复习了一下倒是不难 。

吔我大炮!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
int main(void)
{
    LL  a,b,c; cin>>a>>b>>c;
    if(c>=a*b)puts("YES");
    else puts("NO");
    return 0;
}

梦间

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],b[N];
int main(void)
{
    int t; cin>>t;
    while(t--)
    {
        cin>>a[0]>>b[0]>>a[1]>>b[1]>>a[2]>>b[2];
        int flag=0;
        if(a[0]==0&&a[1]+a[2]==0) flag=1;
        if(a[1]==0&&a[0]+a[2]==0) flag=1;
        if(a[2]==0&&a[1]+a[0]==0) flag=1;
        
        if(b[0]==0&&b[1]+b[2]==0) flag=1;
        if(b[1]==0&&b[0]+b[2]==0) flag=1;
        if(b[2]==0&&b[1]+b[0]==0) flag=1;
        
        if(flag) puts("YES");
        else puts("NO");
    }
    return 0;
}

坠入

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],b[N];
int main(void)
{
    int t; cin>>t;
    while(t--)
    {
        cin>>a[0]>>b[0]>>a[1]>>b[1]>>a[2]>>b[2];
        int flag=0;
        if(a[0]==(a[1]+a[2])/2.0) flag=1;
        if(a[1]==(a[0]+a[2])/2.0) flag=1;
        if(a[2]==(a[1]+a[0])/2.0) flag=1;
        
        if(b[0]==(b[1]+b[2])/2.0) flag=1;
        if(b[1]==(b[0]+b[2])/2.0) flag=1;
        if(b[2]==(b[1]+b[0])/2.0) flag=1;
        
        if(flag) puts("YES");
        else puts("NO");
    }
    return 0;
}

漫步

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
void solve(int x)
{
    vector<int>ve;
    while(x) ve.push_back(x%2),x/=2;
    for(int i=0;i<ve.size();i++)
    {
        if(ve[i]==0){
            cout<<(1<<i)<<'\n';
            return;
        }
    }
    cout<<-1<<'\n';
}
int main(void)
{
    int t; cin>>t;
    while(t--)
    {
        int x; cin>>x;
        solve(x);
    }
    return 0;
}

秘藏

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],b[N],n,k,f[N][2];
int main(void)
{
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    memset(f,-1,sizeof f);
    f[0][0]=0;
    for(int i=1;i<=n;i++)
    {
        if(f[i-1][0]!=-1) f[i][0]=f[i-1][0]+a[i];
        if(f[i-1][1]!=-1) f[i][1]=f[i-1][1]+b[i];
        if(f[i-1][0]>=k)  f[i][1]=max(f[i][1],f[i-1][0]-k+b[i]);
        if(f[i-1][1]>=k)  f[i][0]=max(f[i][0],f[i-1][1]-k+a[i]);
    }
    cout<<max(f[n][0],f[n][1])<<'\n';
    return 0;
}

回响

处理两边边界,而后对于中间0填贪心的填,从大端点到小端点填,从大到小填而后再上下震荡。 例如5 0 0 0 3 就是 5 4 3 4 3

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n;
int main(void)
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    int l=0;
    while(l+1<=n&&a[l+1]==0) l++;
    if(l==n){
        for(int i=1;i<=n;i++) cout<<i<<" ";
        return 0;
    }
    for(int i=l,j=a[l+1]+1;i>=1;i--,j++) a[i]=j;
    int r=n+1;
    while(r-1>=1&&a[r-1]==0) r--;
    for(int i=r,j=a[r-1]+1;i<=n;i++,j++) a[i]=j;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==0)
        {
            int j=i;
            while(j+1<=n&&a[j+1]==0) j++;
            if(a[i-1]>=a[j+1]){
                for(int z=i;z<=j;z++){
                    a[z]=a[z-1]-1;
                    if(a[z-1]==a[j+1]+1) a[z]=a[j+1];
                    else if(a[z-1]==a[j+1]) a[z]=a[j+1]+1;
                }
            }else{
                for(int z=j;z>=i;z--){
                    a[z]=a[z+1]-1;
                    if(a[z+1]==a[i-1]+1) a[z]=a[i-1];
                    else if(a[z+1]==a[i-1]) a[z]=a[i-1]+1;
                }
            }
        }
    }
    int flag=1;
    for(int i=2;i<=n;i++) if(abs(a[i]-a[i-1])!=1) flag=0;
    if(flag){
        for(int i=1;i<=n;i++) cout<<a[i]<<" ";
        
    }else cout<<-1;
    return 0;
}

升!龙!

就是一个前缀,后缀,中间的就是修改那段。这里是将树型能成dfs序搞成了区间。 dfs[i],就是i节点在区间中的位置。 rdfs[i],就是i节点的子节点在区间中的最大值。 redfs[i]就是区间i对应树上的节点是啥。 dp[i]是以dp[i]为根的最大子树和。 pre[i]是i到根节点的路径和。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
LL a[N],n,m;
vector< vector<int> > e(N+1);
LL dfn[N],rdfn[N],redfn[N],dp[N],pre[N],idx;
LL lmax[N],rmax[N];
void dfs(int u,int fa)
{
    dfn[u]=++idx;
    redfn[dfn[u]]=u;
    rdfn[u]=dfn[u];
    pre[u]=pre[fa]+a[u];
    dp[u]=a[u];
    for(int i=0;i<e[u].size();i++)
    {
        int j=e[u][i];
        if(j==fa) continue;
        dfs(j,u);
        dp[u]=max(dp[u],dp[j]+a[u]);
        rdfn[u]=max(rdfn[u],rdfn[j]);
    }
}
int main(void)
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=2;i<=n;i++)
    {
        int p; cin>>p;
        e[i].push_back(p);
        e[p].push_back(i);
    }
    dfs(1,0);
    for(int i=1;i<=n;i++) lmax[i]=max(lmax[i-1],pre[redfn[i]]);
    for(int i=n;i>=1;i--) rmax[i]=max(rmax[i+1],pre[redfn[i]]);
    while(m--){
        int x,y; cin>>x>>y;
        LL ans=max(lmax[dfn[x]-1],rmax[rdfn[x]+1]);
        ans=max(ans,pre[y]+dp[x]);
        cout<<ans<<'\n';
    }
    return 0;
}
相关推荐
绒绒毛毛雨15 分钟前
广告推荐算法入门 day1 --项目选型
算法·推荐算法
越城33 分钟前
数据结构中的栈与队列:原理、实现与应用
c语言·数据结构·算法
wang__1230040 分钟前
力扣2094题解
算法·leetcode·职场和发展
GUIQU.1 小时前
【每日一题 | 2025年5.5 ~ 5.11】搜索相关题
算法·每日一题·坚持
不知名小菜鸡.1 小时前
记录算法笔记(2025.5.13)二叉树的最大深度
笔记·算法
真的想上岸啊2 小时前
c语言第一个小游戏:贪吃蛇小游戏05
c语言·算法·链表
元亓亓亓2 小时前
LeetCode热题100--206.反转链表--简单
算法·leetcode·链表
诚丞成3 小时前
BFS算法篇——从晨曦到星辰,BFS算法在多源最短路径问题中的诗意航行(上)
java·算法·宽度优先
hongjianMa3 小时前
2024睿抗编程赛国赛-题解
算法·深度优先·图论·caip
czy87874753 小时前
两种常见的C语言实现64位无符号整数乘以64位无符号整数的实现方法
c语言·算法