ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

E. Greedy Shopping

2020-11-18 20:32:01  阅读:241  来源: 互联网

标签:Shopping int ll tree Greedy 区间 min1 sum


题目链接:https://codeforces.ml/contest/1440/my
题意:两种操作  一种是 1~x 取a[i]=max(v,a[i])  第二种操作是给 y的钱 从x~n 每一道菜 价钱a[i] 能买就买并扣钱 

否则就跳过  查询 每次买了多少道菜
思路:线段树维护   查询的时候要用到区间和 来进行区间查询, 要同时维护最大值和区间和, 那么需要max1 

来去掉当前区间的部分区间,即取当前区间的某符合条件的子区间, 同时也要维护min1来剪枝   

操作1中  是min1>=v 时 整个区间就没必要在查询了,  操作2中是  min1>v时  就没有符合的菜在该区间中了

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 #define pb push_back
  5 const int mod=1e9+7;
  6 const int maxn=2e5+10;
  7 struct ac
  8 {
  9     int l,r;
 10     int lazy;
 11     int min1;
 12     int len;
 13     ll max1;
 14     ll sum;
 15 };
 16 ac tree[maxn*4];
 17 
 18 void pushup(int x)
 19 {
 20     tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
 21     tree[x].min1=min(tree[x<<1].min1,tree[x<<1|1].min1);
 22     tree[x].max1=max(tree[x<<1].max1,tree[x<<1|1].max1);
 23 }
 24 
 25 void pushdown(int x)
 26 {
 27     ll v=tree[x].lazy;
 28     if(v)
 29     {
 30         tree[x<<1].lazy=tree[x<<1].min1=tree[x<<1].max1=v;
 31         tree[x<<1].sum=v*tree[x<<1].len;
 32         tree[x<<1|1].lazy=tree[x<<1|1].min1=tree[x<<1|1].max1=v;
 33         tree[x<<1|1].sum=v*tree[x<<1|1].len;
 34         tree[x].lazy=0;
 35     }
 36 }
 37 
 38 
 39 
 40 void build(int x,int l,int r)
 41 {
 42     tree[x].l=l,tree[x].r=r;
 43     tree[x].len=r-l+1;
 44     if(l==r)
 45     {
 46         int v;
 47         cin>>v;
 48         tree[x].max1=tree[x].min1=tree[x].sum=v;
 49     }
 50     else
 51     {
 52         int mid=(l+r)/2;
 53         build(x<<1,l,mid);
 54         build(x<<1|1,mid+1,r);
 55         pushup(x);
 56     }
 57 }
 58 
 59 void update(int x,int l,int r,int v)
 60 {
 61     int L=tree[x].l,R=tree[x].r;
 62     if(tree[x].min1>=v)  //要有等号
 63         return;
 64     if(l<=L&&R<=r&&tree[x].max1<v)
 65     {
 66         tree[x].lazy=tree[x].min1=tree[x].max1=v;
 67         tree[x].sum=1ll*v*tree[x].len;
 68     }
 69     else
 70     {
 71         pushdown(x);
 72         int mid=(L+R)/2;
 73         if(l<=mid) update(x<<1,l,r,v);
 74         if(r>mid) update(x<<1|1,l,r,v);
 75         pushup(x);
 76     }
 77 }
 78 
 79 int query(int x,int l,int r,int &v)
 80 {
 81     if(tree[x].min1>v)
 82         return 0;
 83     int L=tree[x].l,R=tree[x].r;
 84     if(l<=L&&R<=r&&tree[x].sum<=v)
 85     {
 86         v-=tree[x].sum;
 87         return tree[x].len;
 88     }
 89     else
 90     {
 91         int mid=(L+R)/2;
 92         pushdown(x);
 93         int ans=0;
 94         if(l<=mid) ans+=query(x<<1,l,r,v);
 95         if(r>mid) ans+=query(x<<1|1,l,r,v);
 96         return ans;
 97     }
 98 }
 99 
100 
101 
102 int main()
103 {
104     ios::sync_with_stdio(0);
105     cin.tie(0);
106     int n,q;
107     cin>>n>>q;
108     build(1,1,n);
109     while(q--)
110     {
111         int t,x,y;
112         cin>>t>>x>>y;
113         if(t==1)
114         {
115             update(1,1,x,y);
116         }
117         else
118         {
119             cout<<query(1,x,n,y)<<'\n';
120         }
121     }
122 
123 
124 
125 }
View Code

 

标签:Shopping,int,ll,tree,Greedy,区间,min1,sum
来源: https://www.cnblogs.com/winfor/p/14001971.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有