有50%的数据,对于满足2≤i≤n的整数i,Fi=i-1。这些数据中有40%的数据(即所有数据的20%)满足n≤500,m≤20,C≤500。除上述数据,另有40%的数据满足n≤500,m≤20,C≤500。对于100%的数据1≤n≤20000,1≤m≤50,1≤C≤2000。对于满足2≤i≤n的整数i,1≤Fi<i。1≤A,B≤231-1,1≤Q≤10000。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lson x<<1
#define rson x<<1|1
#define X 65536
#define Y 2147483647
using namespace std;
const int maxn=20010;
int n,m,A,B,C,Q,cnt;
int to[maxn],next[maxn],head[maxn],fa[maxn],siz[maxn],son[maxn],top[maxn],p1[maxn],p2[maxn],q[maxn],dep[maxn];
struct node
{
int a[55];
int & operator [] (int b) {return a[b];}
node() {memset(a,0,sizeof(a));}
node operator + (node b)
{
node c;
for(int i=0;i<=m;i++) for(int j=0;i+j<=m;j++) c[i+j]=max(c[i+j],a[i]+b[j]);
return c;
}
node operator * (node b)
{
node c;
for(int i=0;i<=m;i++) c[i]=max(a[i],b[i]);
return c;
}
}s[maxn<<2],sm[maxn<<2],v[maxn];
inline int getint()
{
A=((A^B)+(B/X)+(B*X))&Y,B=((A^B)+(A/X)+(A*X))&Y;
return (A^B)%Q;
}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i!=-1;i=next[i])
{
dep[to[i]]=dep[x]+1,dfs1(to[i]),siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
}
}
void dfs2(int x,int tp)
{
top[x]=tp,p1[x]=++q[0],q[q[0]]=x;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=son[x]) dfs2(to[i],to[i]);
p2[x]=q[0];
}
void build(int l,int r,int x)
{
if(l==r)
{
s[x]=sm[x]=v[q[l]];
return ;
}
int mid=(l+r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
s[x]=s[lson]+s[rson],sm[x]=sm[lson]*sm[rson];
}
void updata(int l,int r,int x,int a)
{
if(l==r)
{
s[x]=sm[x]=v[q[l]];
return ;
}
int mid=(l+r)>>1;
if(a<=mid) updata(l,mid,lson,a);
else updata(mid+1,r,rson,a);
s[x]=s[lson]+s[rson],sm[x]=sm[lson]*sm[rson];
}
node q1(int l,int r,int x,int a,int b)
{
if(a>b) return node();
if(a<=l&&r<=b) return s[x];
int mid=(l+r)>>1;
if(b<=mid) return q1(l,mid,lson,a,b);
if(a>mid) return q1(mid+1,r,rson,a,b);
return q1(l,mid,lson,a,b)+q1(mid+1,r,rson,a,b);
}
node q2(int l,int r,int x,int a,int b)
{
if(a>b) return node();
if(a<=l&&r<=b) return sm[x];
int mid=(l+r)>>1;
if(b<=mid) return q2(l,mid,lson,a,b);
if(a>mid) return q2(mid+1,r,rson,a,b);
return q2(l,mid,lson,a,b)*q2(mid+1,r,rson,a,b);
}
inline node ask(int x,int y)
{
if(x==y) return node();
y=fa[y];
node ret;
while(top[x]!=top[y])
{
ret=ret*q2(1,n,1,p1[top[y]],p1[y]);
y=fa[top[y]];
}
ret=ret*q2(1,n,1,p1[x],p1[y]);
return ret;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<‘0‘||gc>‘9‘) {if(gc==‘-‘) f=-f; gc=getchar();}
while(gc>=‘0‘&&gc<=‘9‘) ret=ret*10+(gc^‘0‘),gc=getchar();
return ret*f;
}
inline void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
int main()
{
n=rd(),m=rd(),A=rd(),B=rd(),Q=rd();
int i,j,a,b;
memset(head,-1,sizeof(head));
for(i=2;i<=n;i++) fa[i]=rd(),add(fa[i],i);
dep[1]=1,dfs1(1),dfs2(1,1);
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++) v[i][j]=getint();
sort(v[i].a+1,v[i].a+m+1);
}
build(1,n,1);
C=rd();
for(i=1;i<=C;i++)
{
if(!rd())
{
a=rd();
for(j=1;j<=m;j++) v[a][j]=getint();
sort(v[a].a+1,v[a].a+m+1);
updata(1,n,1,p1[a]);
}
else a=rd(),b=rd(),printf("%d\n",(ask(b,a)+q1(1,n,1,p1[a],p2[a])).a[m]);
}
return 0;
}//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