[BZOJ2164] [mining chain analog + tree split segment tree] +

Online JudgeBzoj2164

The Label : simulation, the chain split tree, the tree segment

Title Description

Cg mighty army discovered a wealth of mineral resources in a city, they intend to implement the new mining strategy in the city. The city can be seen as one with n nodes rooted tree, we put each node with an integer number from 1 to n. For convenience, for any non-root node v, it is an ancestor of any number strictly less than v. Each node in the tree represents a mine, each edge represents a street. As a team leader cg army, you have the m men. You have a two-dimensional dynamic information table, use of Ti, j denotes the i-th row j-th data column. When you are allowed to exploit an area, you can assign your men to the various mine sites. In the i-th mines arrangements j individual can obtain Ti, j units minerals. Allowable withdrawal areas are described: you one pair of occurrences (u, v), ensure that v is u ancestor (defined herein ancestors including u se); u is the area of ​​your control, may be root of u subtree arbitrarily assigned men; u to v is simple paths (including, but not including u v, u = v if u is including) the path of exploration, on which you can select the path up to a mine arrangement men. Your income is the income of the mining arrangements and the underlying mines.

Data for 100%

\(1≤n≤20000\)\(1≤m≤50\)\(1≤C≤2000。\)

For an integer satisfying 2≤i≤n I, \ (1≤Fi <I \) . \ (1 ≦ a, 31 is B≤2 ^ {-1} \) , \ (1≤Q≤10000 \) .

Entry

The first line of input contains five positive integers n, m, A, B, Q. N is the number of occurrences, m is the number of men. A, B, Q is data related to dynamic information. The second row contains the positive integer n-1, the i-th of Fi + 1, represents the father node i + 1. Then you need to use the following method of sequentially generating n sets of data, each data of a total of m. Wherein m i-th data group of m data information table in the i-th row. Followed by a line containing a positive integer C, represents the number of events. Finally, C lines, each describing an event. Each event will first be given an integer of 0 or 1. If the number is 0, then followed by a positive integer p, represents the dynamic information table is updated, you need to generate a set of m data, m pieces of data to replace the p-th row in the information table. If the number is 1, followed by two positive integers u, v, indicates that an area of ​​a mining you can, you need to answer the income mining. They are separated by a space between each number in the same row, with no extra spaces and line breaks.

Data generation method is as follows: each generate a set of m data in ascending order, the replacement dynamic information table row. Wherein, from small to large number of the j-number of column j replacement information table. M times and then the following code to obtain a set of ordered data. (Note that the repeated number may occur) function GetInt A ← ((A xor B ) + (B div X) + (B * X)) and YB ← ((A xor B) + (A div X) + (A * X)) and Y returns (a xor B) mod Q wherein a, B, Q are 32-bit signed integer saved (C / C ++ is signed long int type, pascal of longint type), X-= \ (2 ^ {16} \) (2 ^ 16), the Y = \ (2 ^ {-1} 31 is \) (31 is the power of -12), xor is bitwise-XOR operation, div is integer division, and is bits and operation, mod is modulo operation. Since leaving only the lower 31, we do not consider the readily available data overflow. (Note that each of A and B will be changed)

Export

For each mining event (event begins with 1), the output line of an integer, for each of the gains.

Sample

Input

10 5 1 2 10
1 1 3 3 4 4 6 6 9
4
1 6 3
1 9 1
0 1
1 1 1

Output

1
9
12

answer

Questions plane information was chaotic. The following questions about the meaning roughly handled

There is a city with n nodes rooted tree, and the number is less than the descendants number to ensure ancestor.

Do you have personal m, j arrange individual can get Tij income (Tij with a two-dimensional table is given) in the i-th point. But the location of your schedule is limited. If you were given a mining point (u, v) (v u is the ancestor), then you are free to arrange people in the sub-tree u in; and in the path vu you can only pick one mine release (when U! not included u) time = v. Nowhere else can not release. Please find the maximum benefits.

The first line is \ (n-, m, A, B, Q \) . (Where \ (A, B, Q \ ) for generating data)

The second line number to n-1, represents the i-th father node i + 1.

A third line integer \ (C \) , operands.

The next \ (C \) line, if the number is diverted to the beginning \ (0 \) you press the face questions asked to update \ (Tij \) table, if \ (1 \) behind a pair of integers \ ((u , v) \) indicates that the current mining sites can be opened.

For each \ (1 \) operation, the output was the largest gains. As for how the data generated by the original title to see the face.

See \ (n, m \) data range is actually not so large. \ (1≤n≤20000 \) , \ (1≤m≤50 \) , \ (1≤C≤2000. \)

We press the idea of ​​violence simulation again, regardless of what the update, ask each have to re-do it again.

For the current query \ ((U, V) \) : go to resolve \ (U \) subtree, this part of the tree with Dp solution, defined state \ (dp [x] [i ] \) indicates to \ (X \) is the subtree rooted in the arrangement \ (I \) maximum benefit individuals (since n, m little product space no problem). Dp backpack when transferring mode transition like, which again tree down time complexity Dp \ (O (N \ CDOT M ^ 2) \) . Consider uv path to go directly to the most violent \ (O (N) \) jump up, to enumerate the current point \ (x \) the number of arranged \ (i \) , with \ (T [x] [ I] \) to update the answer, \ (ANS = max (ANS, DP [U] [mi The] + T [X] [I]) \) .

In summary, the most violent engage, the complexity of a single operation is \ (O (N \ CDOT 2 M + N ^ \ CDOT M) \) .


Look this way, the time complexity of a single operation seems decent, focused on how the group is operating, it will be updated \ (Tij \) table.

Since it is a problem tree, it is easy to think of a tree line to maintain.

The above ideas by violence go again. For inquiries \ ((U, v) \) , first to solve the \ (u \) subtree. Dp is still considered a tree, all values except the package up the discharge node, with \ (DFS \) order sub-tree in the interval represented by the interval to complete segment tree merge operations.

Engage a structure \ (Mine \) encapsulated.

struct Mine{
    int a[52];//x.a[i] (1<=i<=m) 表示在x这个点放i个人的最大收益
    void init(){//初始化,更新数据
        for(int i=1;i<=m;++i)a[i]=getnum();
        sort(a+1,a+m+1);
    }
    Mine operator +(const Mine &b)const{//运算符重载,表示合并操作
        Mine res;memset(res.a,0,sizeof(res.a));
        for(register int i=1;i<=m;++i)for(register int j=0;j<=i;++j)
        res.a[i]=max(res.a[i],a[j]+b.a[i-j]);
        return res;
    }
};

Corresponding contribution follows, each node in the tree segment \ (Node \) stored on two values, sumand ma(with the structure noted above are \ (Mine \) represented).

sumPraying is now to use the tree mais to be uv path will get used.

For each node in the tree segment \ (Node \) , provided corresponding interval \ ([l, r] \) , are sumall in order dfs [l, r] between the tree nodes combined result of , which is just put these points in the biggest beneficiary; and main these points one point , put the maximum benefit of the people (you probably know then how to seek contributions on the path, that is a cross-sectional jump up the tree, then the tree line to find the best value range ma).

struct node{
    Mine ma,sum;
}b[N<<2];

inline Mine Max(Mine x,Mine y){
    for(int i=1;i<=m;++i)x.a[i]=max(x.a[i],y.a[i]);
    return x;
}

inline void Up(int o){
    b[o].ma=Max(b[o<<1].ma,b[o<<1|1].ma);
    b[o].sum=b[o<<1].sum+b[o<<1|1].sum;
}

void build(int o,int l,int r){
    if(l==r){
        b[o].ma=b[o].sum=st[l];
        return;
    }
    int mid=l+r>>1;
    build(o<<1,l,mid);build(o<<1|1,mid+1,r);
    Up(o);
}

So for the sub-tree u, query intervals and each operation sumjust fine.

For the sake of contribution uv path is above the spoilers as a direct set of tree chain split in (O (logN) \) \ jump up in time, and then query interval most value, and update the answer.

The complete code is as follows, attention to detail, note cards often.

#include<bits/stdc++.h>
#define N 20010
using namespace std;
const int X=1<<16,Y=(1<<31)-1;
inline int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x;
}
int n,m,A,B,C;


struct edge{
    int to,nxt;
}e[N<<1];
int head[N],cnt;
inline void link(int u,int v){
    e[++cnt].to=v,e[cnt].nxt=head[u];
    head[u]=cnt;
}

inline int getnum(){
    A=((A^B)+B/X+B*X)&Y;
    B=((A^B)+A/X+A*X)&Y;
    return (A^B)%C;
}
struct Mine{
    int a[52];
    void init(){
        for(int i=1;i<=m;++i)a[i]=getnum();
        sort(a+1,a+m+1);
    }
    Mine operator +(const Mine &b)const{
        Mine res;memset(res.a,0,sizeof(res.a));
        for(register int i=1;i<=m;++i)for(register int j=0;j<=i;++j)
        res.a[i]=max(res.a[i],a[j]+b.a[i-j]);
        return res;
    }
}st[N];
inline Mine Max(Mine x,Mine y){
    for(int i=1;i<=m;++i)x.a[i]=max(x.a[i],y.a[i]);
    return x;
}

struct node{
    Mine ma,sum;
}b[N<<2];

inline void Up(int o){
    b[o].ma=Max(b[o<<1].ma,b[o<<1|1].ma);
    b[o].sum=b[o<<1].sum+b[o<<1|1].sum;
}

void build(int o,int l,int r){
    if(l==r){
        b[o].ma=b[o].sum=st[l];
        return;
    }
    int mid=l+r>>1;
    build(o<<1,l,mid);build(o<<1|1,mid+1,r);
    Up(o);
}
void change(int o,int l,int r,int x){
    if(l==r){
        b[o].ma.init();
        b[o].sum=b[o].ma;
        return;
    }
    int mid=l+r>>1;
    if(x<=mid)change(o<<1,l,mid,x);
    else change(o<<1|1,mid+1,r,x);
    Up(o);
}
Mine asksum(int o,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr)return b[o].sum;
    int mid=l+r>>1;
    if(qr<=mid)return asksum(o<<1,l,mid,ql,qr);
    if(ql>mid)return asksum(o<<1|1,mid+1,r,ql,qr);
    return asksum(o<<1,l,mid,ql,mid)+asksum(o<<1|1,mid+1,r,mid+1,qr);   
}
Mine askma(int o,int l,int r,int ql,int qr){
    if(ql<=l&&r<=qr)return b[o].ma;
    int mid=l+r>>1;
    if(qr<=mid)return askma(o<<1,l,mid,ql,qr);
    if(ql>mid)return askma(o<<1|1,mid+1,r,ql,qr);
    return Max(askma(o<<1,l,mid,ql,mid),askma(o<<1|1,mid+1,r,mid+1,qr));
}

int L[N],R[N],fa[N],dfn=0;
int son[N],dep[N],top[N],sz[N];
void dfs(int x){
    sz[x]=1;
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        fa[y]=x;dep[y]=dep[x]+1;
        dfs(y);
        sz[x]+=sz[y];
        if(sz[y]>sz[son[x]])son[x]=y;
    }
}
void redfs(int x,int tp){
    L[x]=++dfn;top[x]=tp;
    if(son[x])redfs(son[x],tp);
    for(int i=head[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y!=son[x])redfs(y,y);
    }
    R[x]=dfn;
}
inline Mine jump(int x,int y){
    Mine res;memset(res.a,0,sizeof(res));
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        res=Max(res,askma(1,1,n,L[top[x]],L[x]));
        x=fa[top[x]];
    }
    if(L[x]>L[y])swap(x,y);
    res=Max(res,askma(1,1,n,L[x],L[y]));
    return res;
}
int main(){
    n=read(),m=read(),A=read(),B=read(),C=read();
    for(int i=2;i<=n;i++){
        int u=read();link(u,i);
    }
    
    dfs(1);redfs(1,1);
    
    for(int i=1;i<=n;i++)st[L[i]].init();
    
    build(1,1,n);
    
    int T=read();
    while(T--){
        int op=read(),x=read();
        if(op==0)change(1,1,n,L[x]);
        else{
            int y=read();
            Mine tmp=asksum(1,1,n,L[x],R[x]);
            if(x!=y)tmp=tmp+jump(fa[x],y);
            printf("%d\n",tmp.a[m]);
        }   
    }
}

Guess you like

Origin www.cnblogs.com/Tieechal/p/11549623.html