一棵树上,从u走到v,在某点买入,咋之后的某点卖出,求最大利润。
维护正着走和反着走的最大利润。
#include #include #include #include #include #include #include #include #include #include #define fi first #define se second #define pii pair #define ll long long #define inf 1000000000 #define eps 1e-8 using namespace std; const int maxn=100005; int son[maxn],top[maxn],dep[maxn],fa[maxn],siz[maxn],id[maxn],fid[maxn]; int sz; vectorg[maxn]; int val[maxn]; int n,q; struct Node { int mi,mx; int ans; int o; Node(int a,int b,int c,int d):mi(a),mx(b),ans(c),o(d){} Node(){} }node[maxn<<2]; int add[maxn<<2]; void dfs(int u,int f) { siz[u]=1; son[u]=0; for(int i=0;isiz[son[u]]) son[u]=v; siz[u]+=siz[v]; } } void build(int u,int w) { id[u]=++sz; fid[sz]=u; top[u]=w; if(son[u]) build(son[u],w); for(int i=0;i=r) { node[rt].mx+=c; node[rt].mi+=c; add[rt]+=c; return; } pushDown(rt); int m=((l+r)>>1); //Node u={inf,-inf,0}; if(L<=m) update(L,R,c,l,m,rt<<1); if(R>m) update(L,R,c,m+1,r,rt<<1|1); pushUp(rt); } void update(int a,int b,int c) { int f1=top[a],f2=top[b]; while(f1!=f2) { if(dep[f1]dep[b]) swap(a,b); update(id[a],id[b],c,1,n,1); } Node unite(Node a,Node b) { Node u; u.mx=max(a.mx,b.mx); u.mi=min(a.mi,b.mi); u.ans=max(a.ans,b.ans); u.ans=max(u.ans,b.mx-a.mi); u.o=max(a.o,b.o); u.o=max(u.o,a.mx-b.mi); return u; } Node query(int L,int R,int l,int r,int rt) { if(L<=l&&R>=r) return node[rt]; pushDown(rt); Node u=Node(inf,-inf,0,0); int m=((l+r)>>1); if(L<=m) u=unite(u,query(L,R,l,m,rt<<1)); if(R>m) u=unite(u,query(L,R,m+1,r,rt<<1|1)); pushUp(rt); return u; } int query(int u,int v) { int a = top[u], b = top[v]; Node lpath = Node(inf , -inf, 0,0), rpath = Node(inf, -inf, 0,0); while(a != b){ if( dep[a] > dep[b]){ Node res = query(id[a], id[u],1,n,1); //cout<>1); buildTree(l,m,rt<<1); buildTree(m+1,r,rt<<1|1); pushUp(rt); } int main() { int t; int a,b,c; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&val[i]); g[i].clear(); } for(int i=0;i