CF557C Arthur and Table の Solution
对于大众来说权值线段树的入门题,一道写起来让我破防的题目。
首先很套路的固定最大值 ,这时候考虑什么时候答案最小。
首先所有大于 的腿我们要删掉,记这个和为 。其次发现,删掉长度等于 的腿必然是不优的,因为删去了长度等于 的腿代表我还要删掉更多长度小于 的腿来满足条件。
假设长度为 的腿有 个,如果小于 的腿的数量 的话,说明不用删掉长度小于 的腿就能满足条件,这时候算出 是容易的。
如果 的话,这就说明我们需要删掉长度小于 代价前 小的所有腿,如果我们从前往后扫值域的话,就发现我们还要会维护单点修改。
观察到 很小,可以考虑权值线段树解决,维护对于每种代价出现的次数以及和,我们要找到前 小的话直接在上面做线段树二分就行。
找到对应位置以后剩下就是一个求和的事情了,写了两只 的劣解。
可能是太久没写OI了,前前后后写了很久,破防了。
#include<bits/stdc++.h>
using namespace std;
const int N =1e6+10;
struct node{
int sum,num;
}d[N];
vector<int> g[N];
int l[N],D[N],n,sum,num,prelst,ans=INT_MAX,now,V=100000;
void update(int l,int r,int s,int t,int p){
if(l<=s&&t<=r){
d[p].num++,d[p].sum+=s;return ;
}
int mid=(s+t)>>1;
if(l<=mid) update(l,r,s,mid,p<<1);
if(r>mid) update(l,r,mid+1,t,p<<1|1);
d[p].num=d[p<<1|1].num+d[p<<1].num,d[p].sum=d[p<<1|1].sum+d[p<<1].sum;
}
int Querynum(int l,int r,int s,int t,int p){
if(l>r) return 0;
if(l<=s&&t<=r) return d[p].num;
int mid=(s+t)>>1,ans=0;
if(l<=mid) ans+=Querynum(l,r,s,mid,p<<1);
if(r>mid) ans+=Querynum(l,r,mid+1,t,p<<1|1);
return ans;
}
int Query(int s,int t,int p,int num){
if(s==t) return s;
int mid=(s+t)>>1,ans=-1;
if(Querynum(1,mid,1,200,1)>=num) ans=Query(s,mid,p<<1,num);
else if(Querynum(1,t,1,200,1)>=num) ans=Query(mid+1,t,p<<1|1,num);
return ans;
}
int Querysum(int l,int r,int s,int t,int p){
if(l>r) return 0;
if(l<=s&&t<=r) return d[p].sum;
int mid=(s+t)>>1,ans=0;
if(l<=mid) ans+=Querysum(l,r,s,mid,p<<1);
if(r>mid) ans+=Querysum(l,r,mid+1,t,p<<1|1);
return ans;
}
void Add(int x){
for(int i=0;i<g[x].size();i++) update(g[x][i],g[x][i],1,200,1);
now+=g[x].size();
}
int main()
{
int prelst1=0;
cin>>n;
for(int i=1;i<=n;i++) cin>>l[i];
for(int i=1;i<=n;i++) cin>>D[i],g[l[i]].push_back(D[i]),prelst+=D[i],prelst1+=D[i];
for(int i=1;i<=V;i++){
num=0,sum=0;
if(g[i].size()==0) continue;
for(int j=0;j<g[i].size();j++) prelst-=g[i][j];
int len=g[i].size(),pre=len*2-1;
if(now+g[i].size()<=pre){ans=min(ans,prelst),Add(i);continue;}
if(g[i].size()==1){ans=min(ans,prelst1-g[i][0]),Add(i);continue;}
int Q=Query(1,200,1,now-(pre-len));
ans=min(ans,prelst+Querysum(1,Q-1,1,200,1)+(now+len-pre-Querynum(1,Q-1,1,200,1))*Q),Add(i);
}
cout<<ans<<endl;
return 0;
}
/*
10
20 1 15 17 11 2 15 3 16 3
129 114 183 94 169 16 18 104 49 146
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!