hdu5052 Yaoge’s maximum profit 树链剖分

一棵树上,从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


你可能感兴趣的:(树链剖分)