【学习笔记】CF626G Raffles

这还是道数据结构题。事实上看数据范围就能看出来。

类似莫队,考虑在上一个询问的基础上求出答案。

有一个非常显然的结论,每次调整是 O ( 1 ) O(1) O(1)的。道理非常简单,设 a i , j a_{i,j} ai,j表示 i i i号奖池第 j j j张彩票的贡献,当 l i l_i li增加 1 1 1时,显然会拿 i i i奖池的彩票去换比它更大的,因为 a i , j − 1 ′ > a i , j a'_{i,j-1}>a_{i,j} ai,j1>ai,j,那么既然原来的第 j j j张换不过,那么改变过后的 j − 1 j-1 j1肯定也换不过,同理 l i l_i li减少 1 1 1时也最多换一张。

那么直接用线段树就做完了。

细心题,难以评价。

为什么调不对呢。。。。

实锤了,我不会写代码。

#include<bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define inf 0x3f3f3f3f #define db long double #define cpx complex<db> using namespace std; const int N=2e5+5; int n,m,Q; ll sz[N],L[N],val[N]; db res; struct node{ db min,max; int posmin,posmax; }t[N<<2]; void pushup(int p){ t[p].max=max(t[p<<1].max,t[p<<1|1].max); t[p].posmax=(t[p<<1].max>t[p<<1|1].max)?t[p<<1].posmax:t[p<<1|1].posmax; t[p].min=min(t[p<<1].min,t[p<<1|1].min); t[p].posmin=(t[p<<1].min<t[p<<1|1].min)?t[p<<1].posmin:t[p<<1|1].posmin; } void init(int p,int l){ t[p].max=(sz[l]<L[l])?(1.0*val[l]*L[l]/(sz[l]+L[l])/(sz[l]+L[l]+1)):-inf; t[p].min=sz[l]?(1.0*val[l]*L[l]/(sz[l]+L[l]-1)/(sz[l]+L[l])):inf; t[p].posmin=t[p].posmax=l; } void build(int p,int l,int r){ if(l==r){ init(p,l); return; } int mid=l+r>>1; build(p<<1,l,mid),build(p<<1|1,mid+1,r); pushup(p); } db getval(int x){ return 1.0*sz[x]/(sz[x]+L[x])*val[x]; } db calcnow(int x){ return 1.0*val[x]*L[x]/(sz[x]+L[x]-1)/(sz[x]+L[x]); } db calcnext(int x){ return 1.0*val[x]*L[x]/(sz[x]+L[x])/(sz[x]+L[x]+1); } void modify(int p,int l,int r,int x,int type){ if(l==r){ sz[l]+=type; init(p,l); return; } int mid=l+r>>1; x<=mid?modify(p<<1,l,mid,x,type):modify(p<<1|1,mid+1,r,x,type); pushup(p); } void getans(){ build(1,1,n); while(m&&t[1].max>0){ int x=t[1].posmax; modify(1,1,n,x,1); m--; } for(int i=1;i<=n;i++)res+=getval(i); } void Add(int x){ res-=getval(x),L[x]++; modify(1,1,n,x,0); res+=getval(x); } void Move(int x){ res-=getval(x),L[x]--; if(sz[x]>L[x]){ modify(1,1,n,x,-1); m++; } else modify(1,1,n,x,0); res+=getval(x); } int main(){ ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); cin>>n>>m>>Q; for(int i=1;i<=n;i++)cin>>val[i]; for(int i=1;i<=n;i++)cin>>L[i]; cout.precision(20); getans(); for(int i=1;i<=Q;i++){ int op,x; cin>>op>>x; if(op==1)Add(x); else Move(x); while(m&&t[1].max>0){ int x=t[1].posmax; res-=getval(x); modify(1,1,n,x,1); res+=getval(x),m--; } if(sz[x]){ int y=t[1].posmax; if(y!=x&&t[1].max>calcnow(x)){ res-=getval(x)+getval(y); modify(1,1,n,x,-1),modify(1,1,n,y,1); res+=getval(x)+getval(y); } } int y=t[1].posmin; if(y!=x&&sz[x]<L[x]&&calcnext(x)>t[1].min){ res-=getval(x)+getval(y); modify(1,1,n,x,1),modify(1,1,n,y,-1); res+=getval(x)+getval(y); } cout<<res<<"\n"; } }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17529989.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示