BZOJ 4370: [IOI2015]horses马 线段树+贪心+对数
显然如果卖出的话肯定要在同一天卖出.
那么我们只需维护 $max(y_{i}\prod x_{i})$ 即可.
乘法维护不了,取一个对数就好了.
code:
#include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #define N 500003 #define ll long long #define mod 1000000007 #define lson now<<1 #define rson now<<1|1 #define setIO(s) freopen(s".in","r",stdin) using namespace std; double a[N],b[N]; int X[N],Y[N],n; struct node { int id,sum2; double maxv,sum; }s[N<<2]; void pushup(int now) { s[now].sum=s[lson].sum+s[rson].sum; s[now].sum2=(ll)s[lson].sum2*s[rson].sum2%mod; if(s[lson].maxv>s[rson].maxv+s[lson].sum) { s[now].maxv=s[lson].maxv; s[now].id=s[lson].id; } else { s[now].maxv=s[lson].sum+s[rson].maxv; s[now].id=(ll)s[lson].sum2*s[rson].id%mod; } } void build(int l,int r,int now) { if(l==r) { s[now].maxv=a[l]+b[l]; s[now].sum=a[l]; s[now].sum2=X[l]%mod; s[now].id=(ll)X[l]*Y[l]%mod; return; } int mid=(l+r)>>1; build(l,mid,lson),build(mid+1,r,rson),pushup(now); } void update_x(int l,int r,int now,int p,int v) { if(l==r) { X[p]=v; a[p]=log2(v); s[now].maxv=a[l]+b[l]; s[now].sum=a[l]; s[now].sum2=X[l]%mod; s[now].id=(ll)X[l]*Y[l]%mod; return; } int mid=(l+r)>>1; if(p<=mid) update_x(l,mid,lson,p,v); else update_x(mid+1,r,rson,p,v); pushup(now); } void update_y(int l,int r,int now,int p,int v) { if(l==r) { Y[p]=v; b[p]=log2(v); s[now].maxv=a[l]+b[l]; s[now].sum=a[l]; s[now].id=(ll)X[l]*Y[l]%mod; return; } int mid=(l+r)>>1; if(p<=mid) update_y(l,mid,lson,p,v); else update_y(mid+1,r,rson,p,v); pushup(now); } int main() { // setIO("input"); int i,j,m; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%d",&X[i]),a[i]=log2(X[i]); for(i=1;i<=n;++i) scanf("%d",&Y[i]),b[i]=log2(Y[i]); build(1,n,1); scanf("%d",&m); printf("%d\n",s[1].id); while(m--) { int w,e,r; scanf("%d%d%d",&w,&e,&r),++e; if(w==1) { update_x(1,n,1,e,r); } else { update_y(1,n,1,e,r); } printf("%d\n",s[1].id); } return 0; }