bzoj 3878 奇怪的计算器 Posted on 2019-12-02 | Views: 线段树. 注意到每次修改后,所有数的相对大小关系不会发生改变. 于是先将所有数排好序,每次修改时,会有一段前缀被改成 $L$ ,一段后缀被改成 $R$ ,中间的正常修改. 用线段树维护这些数即可. 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270//%std#include<bits/stdc++.h>#define endl '\n'using namespace std;typedef long long ll;inline int read(){ int out=0,fh=1; char jp=getchar(); while ((jp>'9'||jp<'0')&&jp!='-') jp=getchar(); if (jp=='-') fh=-1,jp=getchar(); while (jp>='0'&&jp<='9') out=out*10+jp-'0',jp=getchar(); return out*fh;}const int MAXN=1e5+10;int a[MAXN],b[MAXN];struct node{ int val,x,addtag,multag,sxtag,settag; node() { addtag=sxtag=settag=0; multag=1; }}Tree[MAXN<<2];#define root Tree[o]void BuildTree(int o,int l,int r){ root.val=root.x=0; if(l==r) { root.val=root.x=a[l]; return; } int mid=(l+r)>>1; BuildTree(o<<1,l,mid); BuildTree(o<<1|1,mid+1,r);}void modify_add(int o,int c){ root.val+=c; root.addtag+=c;}void modify_mul(int o,int c){ root.val*=c; root.addtag*=c; root.multag*=c; root.sxtag*=c;}void modify_sx(int o,int c){ root.val+=root.x*c; root.sxtag+=c;}void modify_set(int o,int c){ root.val=c; root.addtag=root.sxtag=0; root.multag=1; root.settag=c;}void pushdown(int o){ if(root.settag) { modify_set(o<<1,root.settag); modify_set(o<<1|1,root.settag); root.settag=0; } if(root.multag!=1) { modify_mul(o<<1,root.multag); modify_mul(o<<1|1,root.multag); root.multag=1; } if(root.addtag) { modify_add(o<<1,root.addtag); modify_add(o<<1|1,root.addtag); root.addtag=0; } if(root.sxtag) { modify_sx(o<<1,root.sxtag); modify_sx(o<<1|1,root.sxtag); root.sxtag=0; }}void upd_add(int o,int l,int r,int L,int R,int c){ if(L>R) return; if(L<=l && r<=R) return modify_add(o,c); pushdown(o); int mid=(l+r)>>1; if(L<=mid) upd_add(o<<1,l,mid,L,R,c); if(R>mid) upd_add(o<<1|1,mid+1,r,L,R,c);}void upd_mul(int o,int l,int r,int L,int R,int c){ if(L>R) return; if(L<=l && r<=R) return modify_mul(o,c); pushdown(o); int mid=(l+r)>>1; if(L<=mid) upd_mul(o<<1,l,mid,L,R,c); if(R>mid) upd_mul(o<<1|1,mid+1,r,L,R,c);}void upd_sx(int o,int l,int r,int L,int R,int c){ if(L>R) return; if(L<=l && r<=R) return modify_sx(o,c); pushdown(o); int mid=(l+r)>>1; if(L<=mid) upd_sx(o<<1,l,mid,L,R,c); if(R>mid) upd_sx(o<<1|1,mid+1,r,L,R,c);}void upd_set(int o,int l,int r,int L,int R,int c){ if(L>R) return; if(L<=l && r<=R) return modify_set(o,c); pushdown(o); int mid=(l+r)>>1; if(L<=mid) upd_set(o<<1,l,mid,L,R,c); if(R>mid) upd_set(o<<1|1,mid+1,r,L,R,c);}int query(int o,int l,int r,int pos){ if(l==r) return root.val; pushdown(o); int mid=(l+r)>>1; if(pos<=mid) return query(o<<1,l,mid,pos); else return query(o<<1|1,mid+1,r,pos);}int n,m,lb,rb;struct opt{ int op,x;}q[MAXN];char buf[MAXN];int main(){ m=read(),lb=read(),rb=read(); for(int i=1;i<=m;++i) { scanf("%s %d",buf,&q[i].x); if(buf[0]=='+') q[i].op=1; else if(buf[0]=='-') q[i].op=1,q[i].x*=-1; else if(buf[0]=='*') q[i].op=2; else q[i].op=3; } n=read(); for(int i=1;i<=n;++i) a[i]=b[i]=read(); sort(a+1,a+1+n); BuildTree(1,1,n); for(int i=1;i<=m;++i) { int op=q[i].op,x=q[i].x,L,R,pre,suf; if(op==1) { L=1,R=n,pre=0; while(L<=R) { int mid=(L+R)>>1; int v=query(1,1,n,mid); if(v+x<lb) pre=mid,L=mid+1; else R=mid-1; } L=1,R=n,suf=n+1; while(L<=R) { int mid=(L+R)>>1; int v=query(1,1,n,mid); if(v+x>rb) suf=mid,R=mid-1; else L=mid+1; } upd_set(1,1,n,1,pre,lb); upd_set(1,1,n,suf,n,rb); upd_add(1,1,n,pre+1,suf-1,x); } else if(op==2) { L=1,R=n,pre=0; while(L<=R) { int mid=(L+R)>>1; int v=query(1,1,n,mid); if(1LL*v*x<1LL*lb) pre=mid,L=mid+1; else R=mid-1; } L=1,R=n,suf=n+1; while(L<=R) { int mid=(L+R)>>1; int v=query(1,1,n,mid); if(1LL*v*x>1LL*rb) suf=mid,R=mid-1; else L=mid+1; } upd_set(1,1,n,1,pre,lb); upd_set(1,1,n,suf,n,rb); upd_mul(1,1,n,pre+1,suf-1,x); } else { L=1,R=n,pre=0; while(L<=R) { int mid=(L+R)>>1; int v=query(1,1,n,mid); if(1LL*x*a[mid]+v<1LL*lb) pre=mid,L=mid+1; else R=mid-1; } L=1,R=n,suf=n+1; while(L<=R) { int mid=(L+R)>>1; int v=query(1,1,n,mid); if(1LL*x*a[mid]+v>1LL*rb) suf=mid,R=mid-1; else L=mid+1; } upd_set(1,1,n,1,pre,lb); upd_set(1,1,n,suf,n,rb); upd_sx(1,1,n,pre+1,suf-1,x); } } for(int i=1;i<=n;++i) { int pos=lower_bound(a+1,a+1+n,b[i])-a; printf("%d\n",query(1,1,n,pos)); } return 0;}