# bzoj 2164 采矿

http://www.elijahqi.win/archives/3700
Description

Input

Output

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
Sample Output
11
9
12
【样例说明】

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

1 1 1 1 4 7

HINT

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define lc (x<<1)
#define rc (x<<1|1)
#define ll long long
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
return *S++;
}
int x=0,f=1;char ch=gc();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
return x*f;
}
const int N=20020,M=55;
int X=1<<16,Y=~0u>>1,A,B,Q,t[N][M],h[N],num,in[N],out[N],size[N],son[N];
int tp[N],fa[N],dep[N],C,id[N],m,n;
struct node{
int y,next;
}data[N<<1];
inline int getint(){
A=((A^B)+(B/X)+(B*X))&Y;
B=((A^B)+(A/X)+(A*X))&Y;
return (A^B)%Q;
}
inline void insert1(int x,int y){
data[++num].y=y;data[num].next=h[x];h[x]=num;
data[++num].y=x;data[num].next=h[y];h[y]=num;
}
inline void dfs(int x){
size[x]=1;
for (int i=h[x];i;i=data[i].next){
int y=data[i].y;if (y==fa[x]) continue;
fa[y]=x;dep[y]=dep[x]+1;dfs(y);size[x]+=size[y];
if (size[y]>size[son[x]]) son[x]=y;
}
}
inline void dfs1(int x,int top){
in[x]=++num;tp[x]=top;id[num]=x;
if (son[x]) dfs1(son[x],top);
for (int i=h[x];i;i=data[i].next){
int y=data[i].y;if(y==fa[x]||y==son[x]) continue;
dfs1(y,y);
}out[x]=num;
}
ll dp[N<<2][M],dp1[N<<2][M],ans[M],ans1[M];
inline void merge(ll *x,ll *a,ll *b){
for (int i=1;i<=m;++i) x[i]=max(a[i],b[i]);
}
inline void merge1(ll *x,ll *a,ll *b){
static ll v[M];memset(v,0,sizeof(v));
for (int i=0;i<=m;++i) for (int j=0;j<=m-i;++j) v[i+j]=max(v[i+j],a[i]+b[j]);
for (int i=1;i<=m;++i) x[i]=v[i];
}
inline void build(int x,int l,int r){
if (l==r) {
for (int i=1;i<=m;++i) dp[x][i]=dp1[x][i]=t[id[l]][i];return;
}int mid=l+r>>1;
build(lc,l,mid);build(rc,mid+1,r);
merge(dp[x],dp[lc],dp[rc]);merge1(dp1[x],dp1[lc],dp1[rc]);
}
inline void modify(int x,int l,int r,int p){
if (l==r){
for (int i=1;i<=m;++i) dp[x][i]=dp1[x][i]=t[id[p]][i];return;
}int mid=l+r>>1;
if (p<=mid) modify(lc,l,mid,p);else modify(rc,mid+1,r,p);
merge(dp[x],dp[lc],dp[rc]);merge1(dp1[x],dp1[lc],dp1[rc]);
}
inline void qr(int x,int l,int r,int l1,int r1){
if (l1<=l&&r1>=r) {merge(ans,ans,dp[x]);return;}
int mid=l+r>>1;
if (l1<=mid) qr(lc,l,mid,l1,r1);
if (r1>mid) qr(rc,mid+1,r,l1,r1);
}
inline void qr1(int x,int l,int r,int l1,int r1){
if (l1<=l&&r1>=r) {merge1(ans1,ans1,dp1[x]);return;}
int mid=l+r>>1;
if (l1<=mid) qr1(lc,l,mid,l1,r1);
if (r1>mid) qr1(rc,mid+1,r,l1,r1);
}
int main(){
freopen("bzoj2164.in","r",stdin);
for (int i=1;i<=n;++i){
static int v[M];
for (int j=1;j<=m;++j) v[j]=getint();
sort(v+1,v+m+1);
for (int j=1;j<=m;++j) t[i][j]=v[j];
}build(1,1,n);
/*for (int i=1;i<=n;++i){
for (int j=1;j<=m;++j) printf("%d ",t[i][j]);puts("");
}*/
for (int owo=1;owo<=C;++owo){
if (op==0){
for (int j=1;j<=m;++j) v[j]=getint();
sort(v+1,v+m+1);
for (int j=1;j<=m;++j) t[p][j]=v[j];modify(1,1,n,in[p]);
}else{
}