HDU 5735 Born Slippy (分塊+樹上可持久化)

官方博客講的很清楚:點擊打開鏈接

在這裏貼一下做樹上可持久化的代碼僅供參考。

[code]:

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
typedef long long LL;
const int maxn = (1<<16)+5;
const int sqrn = (1<<8)+5;
const int MOD = 1e9+7;

struct Block{
    LL ds[sqrn];
    void init(){
        memset(ds,-1,sizeof(ds));
    }
}A[maxn+sqrn];
int tot,Rt[maxn][sqrn];

struct Nod{
    int b,next;
    void init(int b,int next){
        this->b=b;this->next=next;
    }
}buf[maxn];
int n,E[maxn],len,w[maxn];
char op[5];
LL dp[maxn],ans;

void pre_process(){
    tot = 0;
    for(int i = 0;i < (1<<8);i++){
        A[i].init();
        Rt[0][i] = i;
        tot++;
    }
}
int opr(int a,int b){
    return op[0]=='A'?(a&b):op[0]=='O'?(a|b):(a^b);
}
int update(int id,LL a,int b){
    int new_id = tot++,i;
    for(i = 0;i < (1<<8);i++){
        A[new_id].ds[i] = max(A[id].ds[i],(a+opr(b,i)));
    }
    return new_id;
}
LL query(int vet,int w){
    int i,fr,bk;
    LL ans = 0;
    fr = w>>8;bk = w - (fr<<8);
    for(i = 0;i < (1<<8);i++){
        if(A[Rt[vet][i]].ds[bk]==-1) continue;
        ans = max(ans,A[Rt[vet][i]].ds[bk]+(opr(fr,i)<<8));
    }
    return ans;
}

void init(){
    len = 0;tot = (1<<8);ans = 0;
    memset(E,-1,(n+1)*sizeof(int));
}
void add_edge(int a,int b){
    buf[len].init(b,E[a]);E[a]=len++;
}
void dfs(int u,int pre){
    int i,v;
    dp[u] = query(pre,w[u]);
    ans = (ans+u*(dp[u]%MOD+w[u])%MOD)%MOD;
    for(i = 0;i < (1<<8);i++) Rt[u][i] = Rt[pre][i];
    Rt[u][w[u]>>8] = update(Rt[u][w[u]>>8],dp[u],w[u]-((w[u]>>8)<<8));

    for(i = E[u];i != -1;i = buf[i].next){
        v = buf[i].b;
        dfs(v,u);
    }
}

int main(){
    int i,j,cas,u;
    scanf("%d",&cas);
    pre_process();
    while(cas--){
        scanf("%d%s",&n,op);
        init();
        for(i = 1;i <= n;i++) scanf("%d",&w[i]);
        for(i = 2;i <= n;i++){
            scanf("%d",&u);
            add_edge(u,i);
        }
        dfs(1,0);
        printf("%I64d\n",(ans+MOD)%MOD);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章