首页 > 其他分享 >牛客挑战赛72 总结

牛客挑战赛72 总结

时间:2023-12-29 23:23:28浏览次数:29  
标签:pre rs int tree mid 牛客 72 挑战赛 ls

A

题意:给定一个数组,问有多少 \(i\in [2,n-1],a[i-1]>a[i]<a[i+1]\)。
做法:模拟。

B

题意:按顺序将 \(n\) 个数加入集合,维护前 \(6\) 大的数。对于每个数求出它会将第几个数踢出前 \(6\) 或者不踢出任何其他数。
做法:模拟。可以使用priority_queue实现。但是要注意priority_queue默认大根堆,取相反数即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
    int n;cin>>n;
    int ans=n;
    vector<double> A(n);
    vector<int> Ans;
    for(int i=0;i<n;i++) cin>>A[i],A[i]*=1e8;
    priority_queue<pair<int,int> > q;
    for(int i=0;i<n;i++)
    {
        q.push(make_pair(-A[i],i));
        if(q.size()>6)
        {
            if(q.top().second==i) ans--,Ans.push_back(0);
            else Ans.push_back(q.top().second+1);
            q.pop();
        }
        else Ans.push_back(0);
    }
    cout<<ans<<endl;
    for(auto x:Ans) cout<<x<<' ';
}

C

题意:给定一棵树,带点权。建立一个无向完全图,边 \((u,v)\) 的权值为 \(lca(u,v)\) 的权值。求一条哈密顿路径,使边权和最大。输出这个边权和。\(n\leq 300\)。
做法:
假设哈密顿路径是有向的,则可以看作每个点对应着一条入边一条出边(除了起点终点)。
维护 \(f[x][i]\) 表示以 \(x\) 为根的子树中有 \(i\) 个点的出边经过根 \(x\) 时子树的答案。
可以发现如果一条出边向上经过 \(x\) ,那么它发源于哪个点其实是无关紧要的,这条出边的贡献可能是点 \(x\) 到点 \(1\) (根节点)的路径上的某一个点的点权。
同时,\(i\) 条出边经过根 \(x\) 也意味着子树 \(x\) 中包含了 \(i\) 条路径,也就是有 \(i\) 个终点, \(i\) 个起点 。
考虑转移,将 \(x\) 的一个儿子 \(y\) 的答案合并到 \(x\) 的答案:

\[f'[x][i+j-k]=\min\{f[x][i]+f[y][j]+k\cdot val[x]\} \]

其中枚举 \(k\) 表示将来自于 \(y\) 的出边塞到了 \(x\) 的其他子树中,或者是将来自于其他子树的出边塞到了 \(y\) 中,这二者都会对答案产生 \(val[x]\) 的贡献。
关于 \(k\) 还有一些小细节:
1、\(k\in [0,2\min\{i,j\}]\),假如 \(i<j\) ,则 \(j\) 超出的部分在 \(i\) 中找不到可以链接的位置。
2、\(i+j-k>0\) ,这是为了防止回路的出现。
另外,由于更新前后的 \(f\) 不同,所以用 \(f'\) 表示用子树 \(y\) 更新后的 \(f\) 。
最后用 \(f[1][1]\) 表示答案。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 1e18
const int N=305;
vector<int> son[N];
int n,a[N],f[N][N],s[N],siz[N];
void dfs(int x)
{
    siz[x]=1;
    for(int i=0;i<=n;i++) f[x][i]=-inf;
    f[x][1]=0;
    for(int y:son[x])
    {
        dfs(y);
        for(int i=0;i<=n;i++) s[i]=-inf;
        for(int i=0;i<=siz[x];i++)
            for(int j=0;j<=siz[y];j++)
                for(int k=0;k<=min(i,j)*2;k++)
                    if(i+j-k) s[i+j-k]=max(s[i+j-k],f[x][i]+f[y][j]+k*a[x]);
        siz[x]+=siz[y];
        for(int i=0;i<=n;i++) f[x][i]=s[i];
    }
}
signed main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=2;i<=n;i++)
    {
        int x;cin>>x;
        son[x].push_back(i);
    }
    dfs(1);
    cout<<f[1][1]<<endl;
}

D

题意:给定一个 \(0\sim n-1\) 的排列,\(m\) 次询问 \(l,r,k\) ,问区间 \([l,r]\) 中第 \(k\) 小的未出现过的数。
做法:
如果不询问区间,那么可以用权值线段树解决。
如果询问的区间都是前缀,那么可以用离线后用权值线段树解决。
如果询问任意区间,那么可以用可持久化权值线段树解决,也就是主席树。
权值线段树可以求第 \(k\) 小,反一下就可以求未出现自然数第 \(k\) 小,所以只要把每次加入的数在主席树中新加一列就可以实现区间第 \(k\) 小。

#include<bits/stdc++.h>
using namespace std;
template<class T>inline void read(T &x)
{
	x=0;int f=0;char ch=getchar();
	while(!isdigit(ch))	f=ch=='-',ch=getchar();
	while(isdigit(ch))	x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	x=f?-x:x;
}
const int N=1e6+5;
int tree[N<<5],ls[N<<5],rs[N<<5],rt[N],n,a[N],tot,TOT,m;
#define mid (l+r>>1)
void upd(int l,int r,int pre,int &k,int x,int val)
{
	if(!k)	k=++tot;
	if(l==r)	return tree[k]=val,void();
	if(mid>=x)	rs[k]=rs[pre],upd(l,mid,ls[pre],ls[k],x,val);
	else	ls[k]=ls[pre],upd(mid+1,r,rs[pre],rs[k],x,val);
    tree[k]=tree[ls[k]]+tree[rs[k]];
}
int query(int l,int r,int pre,int k,int rk)
{
    if(l==r) return l;
    if(mid-l+1-(tree[ls[k]]-tree[ls[pre]])>=rk) return query(l,mid,ls[pre],ls[k],rk);
    return query(mid+1,r,rs[pre],rs[k],rk-(mid-l+1-(tree[ls[k]]-tree[ls[pre]])));
}
int main()
{
	read(n),read(m);
    for(int i=1;i<=n;i++)
    {
        read(a[i]);
        a[i]++;
        upd(1,n,rt[i-1],rt[i],a[i],1);
    }
    while(m--)
    {
        int l,r;
        long long rk;
        read(l),read(r),read(rk);
        if(rk>n-(r-l+1)) printf("%lld\n",rk+(r-l+1)-1);
        else printf("%d\n",query(1,n,rt[l-1],rt[r],rk)-1);
    }
	return 0;
}

剩下两题有时间再补(

标签:pre,rs,int,tree,mid,牛客,72,挑战赛,ls
From: https://www.cnblogs.com/napnah/p/17935858.html

相关文章

  • macOS Monterey 12.6.9 (21G726) 正式版发布,ISO、IPSW、PKG 下载
    macOSMonterey12.6.9(21G726)正式版发布,ISO、IPSW、PKG下载本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,或者在虚拟机中启动安装。另外也支持在Windows和Linux中创建可引导介质。2023年9月12日,Apple为macOS和iOS......
  • macOS Monterey 12.6.9 (21G726) Boot ISO 原版可引导镜像
    macOSMonterey12.6.9(21G726)BootISO原版可引导镜像本站下载的macOS软件包,既可以拖拽到Applications(应用程序)下直接安装,也可以制作启动U盘安装,或者在虚拟机中启动安装。另外也支持在Windows和Linux中创建可引导介质。2023年9月12日,Apple为macOS和iOS等旧......
  • 牛客OJ在线编程常见输入输出练习
    练习链接:https://www.nowcoder.com/exam/test/76850250/detail?pid=27976983&examPageSource=Search 题目:A+B(4)输入数据包括多组。每组数据一行,每行的第一个整数为整数的个数n(1<=n<=100),n为0的时候结束输入。接下来n个正整数,即需要求和的每个正整数。示例:输入......
  • T397291 【模板】拓扑排序(加强版)
    原题链接思路找到所有入度为零的点,然后消除其子节点的入度,再把入度为零的点塞入队列中为什么可以这么做呢?一个点能弹出队列,其父节点一定比他先入队,以此类推。。代码#include<bits/stdc++.h>usingnamespacestd;vector<int>G[100005];intin[100005]={0};intmain(){......
  • 【力扣】-1672. 最富有客户的资产总量|刷题打卡-JS
    给你一个 mxn 的整数网格 accounts ,其中 accounts[i][j] 是第 i 位客户在第 j 家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户。示例1:第1位客户的资产......
  • openGauss学习笔记-172 openGauss 数据库运维-备份与恢复-导入数据-分析表172.1 分析
    openGauss学习笔记-172openGauss数据库运维-备份与恢复-导入数据-分析表执行计划生成器需要使用表的统计信息,以生成最有效的查询执行计划,提高查询性能。因此数据导入完成后,建议执行ANALYZE语句生成最新的表统计信息。统计结果存储在系统表PG_STATISTIC中。172.1分析表ANALYZE......
  • 2023"安洵杯"第六届网络安全挑战赛-Misc WP
    dacongのsecret题目我的解答:题目给出一张png图片和一个加密压缩包,压缩包里面还存在另一张jpg图片看名字就知道是盲水印。由于压缩包里的图片提不出来,因此是单图盲水印,我们使用工具得密码d@C0ng1scUt3!!!解压得到另一张图片,010分析一下得到一串字符一眼丁真压缩包逆过......
  • SOJ1972 题解
    题意设\(S\)为一个可重数集,满足所有元素均为非负整数。你可以对\(S\)进行若干次(可以为\(0\)次)如下操作:选择一个非负整数\(x\)满足\(x\)至少在\(S\)中出现了\(2\)次,在\(S\)中删除一个\(x\),并将\((x-1)\)或\((x+1)\)插入\(S\)。如果你选择插入\((x-1)\),你必......
  • 2023安洵杯第六届网络安全挑战赛 WP
    webai_java首先通过附件帐号信件获取到帐号通过base64或者jsfuck可获取提示js和c,审计一下js那么可以看到c函数,运行一下。获取到github项目地址查找提交历史我们发现了源码审计源码发现为可能存在spring–boot未授权绕过在admin的页面下的/post_message/接口存在fastjson解析......
  • 牛客周赛:25
    模板A、小红购物跳转原题点击此:[A题地址](A-小红购物_牛客周赛Round25(nowcoder.com))1、题目大意  小红购买了n件物品,但是对其中部分商品不满意要退货,但是退货要收取手续费,手续为为\(max(5,\lfloor{该商品价格/100}\rfloor)\),问你小红最终需要支出多少钱。2、题目......