#20071-[NOIP2020模拟赛B组Day6]礼物购买【二分】
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                #20071-[NOIP2020模拟赛B组Day6]礼物购买【二分】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                正題
題目鏈接:http://noip.ybtoj.com.cn/contest/105/problem/1
題目大意
nnn個物品,每個價格為viv_ivi?有xix_ixi?個,mmm次,開始有wiw_iwi?元。每次選擇能買的最貴的買,求能買多少。
解題思路
分兩種情況討論,如果wi≥xnoww_i\geq x_{now}wi?≥xnow?那么就二分出一個位置使得買到這里后不能再買了,然后nownownow跳過去。如果wi<xnoww_i< x_{now}wi?<xnow?,那么二分出一個位置使得wi≥xnoww_i\geq x_{now}wi?≥xnow?然后nownownow跳過去。
這樣每次wiw_iwi?會減少一半,所以時間復雜度是O(qlog?wilog?n)O(q\log w_i\log n)O(qlogwi?logn)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1e5+10; struct node{ll v,x; }a[N]; ll n,m,b[N],s[N],k[N]; bool cmp(node x,node y) {return x.v>y.v;} int main() {freopen("present.in","r",stdin);freopen("present.out","w",stdout);scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++)scanf("%lld%lld",&a[i].v,&a[i].x);sort(a+1,a+1+n,cmp);for(ll i=1;i<=n;i++)b[i]=b[i-1]+a[i].v*a[i].x,s[i]=s[i-1]+a[i].x,k[n-i+1]=a[i].v;while(m--){ll q,ans=0,x=0;scanf("%lld",&q);while(x<=n&&q){if(q>=a[x+1].v){ll y=lower_bound(b+x+1,b+1+n,q+b[x])-b;if(y==x)break;ans+=s[y-1]-s[x];q-=b[y-1]-b[x];x=y;if(x>n)break;ans+=q/a[x].v;q%=a[x].v;}else{ll y=upper_bound(k+1,k+1+n,q)-k-1;if(!y)break;x=n-y;}}printf("%lld\n",ans);} }總結
以上是生活随笔為你收集整理的#20071-[NOIP2020模拟赛B组Day6]礼物购买【二分】的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: P3708-koishi的数学题【差分】
 - 下一篇: 高傲是什么意思 高傲的含义