牛客挑战赛72 总结
A
题意:给定一个数组,问有多少
做法:模拟。
B
题意:按顺序将
做法:模拟。可以使用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
题意:给定一棵树,带点权。建立一个无向完全图,边
做法:
假设哈密顿路径是有向的,则可以看作每个点对应着一条入边一条出边(除了起点终点)。
维护
可以发现如果一条出边向上经过
同时,
考虑转移,将
其中枚举
关于
1、
2、
另外,由于更新前后的
最后用
#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
题意:给定一个
做法:
如果不询问区间,那么可以用权值线段树解决。
如果询问的区间都是前缀,那么可以用离线后用权值线段树解决。
如果询问任意区间,那么可以用可持久化权值线段树解决,也就是主席树。
权值线段树可以求第
#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;
}
剩下两题有时间再补(
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [翻译] 为什么 Tracebit 用 C# 开发
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· 刚刚!百度搜索“换脑”引爆AI圈,正式接入DeepSeek R1满血版