DDP

DDP
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
    char ch;x=0;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
#define mid ((l+r)>>1)
namespace Miracle{
const int N=1e5+5;
const int inf=0x3f3f3f3f;
int n,m;
struct node{
    int nxt,to;
}e[2*N];
int hd[N],cnt;
void add(int x,int y){
    e[++cnt].nxt=hd[x];
    e[cnt].to=y;
    hd[x]=cnt;
}
int Max(int x,int y){
    return x>y?x:y;
}
struct tr{
    int a[2][2];
    void init(){
        memset(a,0,sizeof a);
    }
    tr friend operator *(const tr&a,const tr &b){
        tr c;//c.init();
        c.a[0][0]=Max(a.a[0][0]+b.a[0][0],a.a[0][1]+b.a[1][0]);
        c.a[0][1]=Max(a.a[0][0]+b.a[0][1],a.a[0][1]+b.a[1][1]);
        c.a[1][0]=Max(a.a[1][0]+b.a[0][0],a.a[1][1]+b.a[1][0]);
        c.a[1][1]=Max(a.a[1][0]+b.a[0][1],a.a[1][1]+b.a[1][1]);
        return c;
    }
}S,A,B;
struct seg{
    int ls,rs;
    tr f;    
}t[4*N];
int tot;
int rt[N];
void pushup(int x){
    t[x].f=t[t[x].rs].f*t[t[x].ls].f;
}
void build(int &x,int l,int r){
    x=++tot;
    if(l==r) {
        t[x].f.a[1][1]=-inf;return;
    }
    build(t[x].ls,l,mid);
    build(t[x].rs,mid+1,r);
    pushup(x);
}
void upda(int x,int l,int r,int p,int c1,int c2){//pos k add c
    if(l==r){
        cout<<" upda "<<c1<<" "<<c2<<endl;
    //a[0][0],a[1][0]
            t[x].f.a[0][0]+=c1;
            t[x].f.a[1][0]+=c1;
    //a[0][1]
            t[x].f.a[0][1]+=c2;
        return;
    }
    if(p<=mid) upda(t[x].ls,l,mid,p,c1,c2);
    else upda(t[x].rs,mid+1,r,p,c1,c2);
    pushup(x);
}
tr query(int x,int l,int r,int L,int R){
    if(L<=l&&r<=R){
        cout<<t[x].f.a[0][0]<<" "<<t[x].f.a[0][1]<<" "<<t[x].f.a[1][0]<<" "<<t[x].f.a[1][1]<<endl;
        return t[x].f;
    }
    tr ret;ret.init();
    if(mid<R) ret=ret*query(t[x].rs,mid+1,r,L,R);
    if(L<=mid) ret=ret*query(t[x].ls,l,mid,L,R);
    return ret;
}
int sz[N],son[N],dep[N],top[N],dfn[N],nd[N];
int df,fa[N];

void dfs1(int x,int d){
    sz[x]=1;
    dep[x]=d;
    for(reg i=hd[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==fa[x]) continue;
        fa[y]=x;
        dfs1(y,d+1);
        sz[x]+=sz[y];
        if(sz[y]>sz[son[x]]) son[x]=y;
    }
}
int v[N];
int tmp[N];
void dfs2(int x){
    dfn[x]=++df;
    if(!top[x]) top[x]=x;
    if(son[x]) top[son[x]]=top[x],dfs2(son[x]);
    for(reg i=hd[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==fa[x]||y==son[x]) continue;
        dfs2(y); 
    }
    if(!son[x]) {
        build(rt[top[x]],dfn[top[x]],dfn[x]);
        nd[top[x]]=x;
    }
}
int f[N][2];
tr wrk(int x,int c){
    cout<<" wrk "<<x<<" "<<c<<endl;
//    cout<<" wrk "<<x<<" "<<c<<endl;
    cout<<" rt "<<rt[top[x]]<<endl;
    upda(rt[top[x]],dfn[top[x]],dfn[nd[top[x]]],dfn[x],0,c-v[x]);
    while(1){
//        cout<<" xx "<<x<<endl;
        const tr &tmp=S*query(rt[top[x]],dfn[top[x]],dfn[nd[top[x]]],dfn[top[x]],dfn[nd[top[x]]]);
        x=top[x];
        if(fa[x]){
            int y=fa[x];
            upda(rt[top[y]],dfn[top[y]],dfn[nd[top[y]]],dfn[y],Max(tmp.a[0][0],tmp.a[0][1])-Max(f[x][0],f[x][1]),tmp.a[0][0]-f[x][0]);
            f[x][0]=tmp.a[0][0];
            f[x][1]=tmp.a[0][1];
        }else{
            return tmp;
        }
        x=fa[x];
    }
}
int main(){
    rd(n);rd(m);
    for(reg i=1;i<=n;++i) rd(tmp[i]);
    int x,y;
    for(reg i=1;i<n;++i){
        rd(x);rd(y);
        add(x,y);add(y,x);
    }
    dfs1(1,1);
//    cout<<" after dfs1 "<<endl;
    dfs2(1);
    prt(dfn,1,n);
    prt(son,1,n);
    prt(top,1,n);
    prt(nd,1,n);
//    cout<<" after dfs2 "<<endl;
    for(reg i=1;i<=n;++i){
        A=wrk(i,tmp[i]);
//        cout<<" A "<<A.a[0][0]<<" "<<A.a[0][1]<<endl;
    }
    int c;
    while(m--){
        rd(x);rd(c);
        A=wrk(x,c);
        v[x]=c;
        printf("%d\n",Max(A.a[0][0],A.a[0][1]));
    }
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2019/4/4 19:26:30
*/
View Code

 

上一篇:详解String的intern方法


下一篇:DDP入门