CodeForces - 635D Factory Repairs —— 點更新 區間查詢
阿新 • • 發佈:2018-11-12
題意:
工廠生產產品,開始時每天生產b個,維修連續的k天后變成每天生產a個
第di天有需求量為ai的訂單,每個訂單隻能當天生產,不能今天生產的明天賣
問若從某天開始維修,能完成的訂單裡的產品總數
思路:
用線段樹維護,每個節點裡分別記錄這個區間內修理之前和修理之後能完成的產品總數,詢問時分別查詢修理前和修理後
要注意訂單是可以疊加的,點更新時不是賦值是累加
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #include <string> #include <cstring> #include <algorithm> using namespace std; #define ll long long #define max_ 200100 #define mod 1000000007 #define inf 0x3f3f3f3f struct node { int l,r; ll w1,w2; }; struct node tree[max_*4]; int n,k,q; ll a,b; void built(int i,int l,int r) { tree[i].l=l; tree[i].r=r; tree[i].w1=0; tree[i].w2=0; if(l==r) return; int mid=(l+r)>>1; built(i<<1,l,mid); built(i<<1|1,mid+1,r); } void updata(int i,int x,ll v) { if(tree[i].l==tree[i].r) { tree[i].w1=min(v+tree[i].w1,b); tree[i].w2=min(v+tree[i].w2,a); return; } int mid=(tree[i].l+tree[i].r)>>1; if(x<=mid) updata(i<<1,x,v); else updata(i<<1|1,x,v); tree[i].w1=tree[i<<1].w1+tree[i<<1|1].w1; tree[i].w2=tree[i<<1].w2+tree[i<<1|1].w2; } ll query(int i,int l,int r,int ti) { if(tree[i].l==l&&tree[i].r==r) { if(ti==1) return tree[i].w1; else return tree[i].w2; } int mid=(tree[i].l+tree[i].r)>>1; if(r<=mid) return query(i<<1,l,r,ti); else if(l>mid) return query(i<<1|1,l,r,ti); else return query(i<<1,l,mid,ti)+query(i<<1|1,mid+1,r,ti); } int main(int argc, char const *argv[]) { scanf("%d%d%lld%lld%d",&n,&k,&a,&b,&q); built(1,1,n); while(q--) { int ti,data,num; scanf("%d",&ti); if(ti==1) { scanf("%d%d",&data,&num); updata(1,data,num); } else { scanf("%d",&data); ll ans=0; if(data>1) ans+=query(1,1,data-1,1); if(data+k<=n) ans+=query(1,data+k,n,2); printf("%lld\n",ans); } } return 0; }