CodeForces 1439 - Problem C - Greedy Shopping - 線段樹
阿新 • • 發佈:2020-11-18
這題實在把我心態搞崩了
WA了一萬發
先留著吧,以後補,今天實在沒心情補了
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int N = 2e5+50; struct node{ ll mx; ll mn; ll sum; }; int n,q; ll arr[N<<2]; ll lazy[N<<2]; node tree[N<<2]; void pushdown(int rt,int l,int r){ if(lazy[rt]){ int mid = l+r>>1; int ls = rt<<1; int rs = rt<<1|1; tree[ls].mx = tree[rs].mx = tree[ls].mn = tree[rs].mn = lazy[rt]; tree[ls].sum = (mid-l+1) * lazy[rt]; tree[rs].sum = (r-mid) * lazy[rt]; lazy[rt] = 0; } } void pushup(int rt){ tree[rt].mx = tree[rt<<1].mx; tree[rt].mn = tree[rt<<1|1].mn; tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum; } void build(int l,int r,int rt){ if(l==r){ tree[rt].sum = tree[rt].mx = tree[rt].mn = arr[l]; }else{ build(l,l+r>>1,rt<<1); build(1+(l+r>>1),r,rt<<1|1); pushup(rt); } } void update(int l,int r,int rt,int ul,int ur,ll v){ if(ul <= l && ur >= r){ if(tree[rt].mn >= v)return; else if(tree[rt].mx <= v){ tree[rt].mn=tree[rt].mx=v; tree[rt].sum=(r-l+1)*v; lazy[rt]=v; return; }else{ int mid=l+r>>1; pushdown(rt,l,r); update(l,mid,rt<<1,l,mid,v); update(mid+1,r,rt<<1|1,mid+1,r,v); pushup(rt); } }else{ int mid=l+r>>1; pushdown(rt,l,r); if(ul<=mid){ update(l,mid,rt<<1,ul,ur,v); } if(ur>mid){ update(mid+1,r,rt<<1|1,ul,ur,v); } pushup(rt); } } ll query_mx(int l,int r,int rt,int pos){ // 區間最大值實際上就在左端點. if(tree[rt].mx==tree[rt].mn){ return tree[rt].mx; }else{ pushdown(rt,l,r); int mid = l+r>>1; if(pos <= mid)return query_mx(l,mid,rt<<1,pos); else return query_mx(mid+1,r,rt<<1|1,pos); } } ll query_sum(int l,int r,int rt,int ql,int qr){ if(ql <= l && qr >= r){ return tree[rt].sum; }else{ pushdown(rt,l,r); int mid = l+r>>1; ll ans = 0; if(ql <= mid)ans += query_sum(l,mid,rt<<1,ql,qr); if(qr > mid) ans += query_sum(mid+1,r,rt<<1|1,ql,qr); return ans; } } pii getans(int x,ll v){ int l = x,r = n; int bg = -1,ed = -1; while(l <= r){ int mid = l+r>>1; if(query_mx(1,n,1,mid) <= v){ bg = mid; r = mid-1; }else{ l = mid+1; } } if(bg==-1)return make_pair(-1,-1); l = bg; r = n; while(l <= r){ int mid = l+r>>1; if(query_sum(1,n,1,bg,mid) <= v){ ed = mid; l = mid+1; }else{ r = mid-1; } } return make_pair(bg,ed); } int main(){ scanf("%d%d",&n,&q); for(int i=1;i<=n;i++){scanf("%lld",&arr[i]);} build(1,n,1); int x,y; ll z; while(q--){ scanf("%d%d%lld",&x,&y,&z); if(x==1){ update(1,n,1,1,y,z); }else{ int ans = 0; while(1){ pii g = getans(y,z); if(g.first==-1)break; ans += g.second-g.first+1; y=g.second+1; z-=query_sum(1,n,1,g.first,g.second); if(y>n)break; } printf("%d\n",ans); } } // system("pause"); return 0; }