E. Greedy Shopping
作者:互联网
题目链接: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