牛客周赛 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;
}
相关推荐
老马啸西风1 分钟前
Neo4j GDS-09-neo4j GDS 库中路径搜索算法实现
网络·数据库·算法·云原生·中间件·neo4j·图数据库
xiongmaodaxia_z733 分钟前
python每日一练
开发语言·python·算法
zy_destiny1 小时前
【非机动车检测】用YOLOv8实现非机动车及驾驶人佩戴安全帽检测
人工智能·python·算法·yolo·机器学习·安全帽·非机动车
rigidwill6662 小时前
LeetCode hot 100—搜索二维矩阵
数据结构·c++·算法·leetcode·矩阵
短尾黑猫2 小时前
[LeetCode 1696] 跳跃游戏 6(Ⅵ)
算法·leetcode
矛取矛求2 小时前
栈与队列习题分享(精写)
c++·算法
袖清暮雨2 小时前
【专题】搜索题型(BFS+DFS)
算法·深度优先·宽度优先
LuckyLay2 小时前
LeetCode算法题(Go语言实现)_46
算法·leetcode·golang
alicema11112 小时前
Python-Django集成yolov识别模型摄像头人数监控网页前后端分离
开发语言·后端·python·算法·机器人·django