1. 程式人生 > >CF 1093G Multidimensional Queries——線段樹(消去絕對值符號)

CF 1093G Multidimensional Queries——線段樹(消去絕對值符號)

題目:http://codeforces.com/contest/1093/problem/G

只好看看題解:https://codeforces.com/blog/entry/63877

主要是把絕對值符號消掉,變成列舉正負。因為答案不會變差,所以不用管符號應該是什麼,直接對應地取 max 、 min 即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls Ls[cr]
#define rs Rs[cr]
using namespace std;
const int N=2e5+5,M=N<<1,K=10,tK=35,INF=5e6+5;
int n,k,lm,bin[K],Q,a[N][K],tot,Ls[M],Rs[M];
int Mx(int a,int b){return a>b?a:b;}
int Mn(int a,int b){return a<b?a:b;}
struct Node{
  int mx[tK],mn[tK];
  Node operator+ (const Node &b)const
  {
    Node c;
    for(int i=0;i<lm;i++)
      {
	c.mx[i]=Mx(mx[i],b.mx[i]);
	c.mn[i]=Mn(mn[i],b.mn[i]);
      }
    return c;
  }
}sm[M];
int rdn()
{
  int ret=0;bool fx=1;char ch=getchar();
  while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
  while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
  return fx?ret:-ret;
}
void dfs(int cr,int lj,int s,int id,int bh)
{
  if(cr>k)
    {
      sm[bh].mn[s]=sm[bh].mx[s]=lj;
      return;
    }
  dfs(cr+1,lj+a[id][cr],s|bin[cr],id,bh);
  dfs(cr+1,lj-a[id][cr],s,id,bh);
}
void build(int l,int r,int cr)
{
  if(l==r){dfs(1,0,0,l,cr);return;}
  int mid=l+r>>1;
  ls=++tot;build(l,mid,ls);
  rs=++tot;build(mid+1,r,rs);
  sm[cr]=sm[ls]+sm[rs];
}
void updt(int l,int r,int cr,int p)
{
  if(l==r){dfs(1,0,0,l,cr);return;}
  int mid=l+r>>1;
  if(p<=mid)updt(l,mid,ls,p);
  else updt(mid+1,r,rs,p);
  sm[cr]=sm[ls]+sm[rs];
}
Node query(int l,int r,int cr,int L,int R)
{
  if(l>=L&&r<=R)return sm[cr];
  int mid=l+r>>1;
  if(L>mid)return query(mid+1,r,rs,L,R);
  if(R<=mid)return query(l,mid,ls,L,R);
  return query(l,mid,ls,L,R)+query(mid+1,r,rs,L,R);
}
int main()
{
  n=rdn();k=rdn();lm=(1<<k);
  bin[1]=1;for(int i=2;i<=k;i++)bin[i]=bin[i-1]<<1;
  for(int i=1;i<=n;i++)
    for(int j=1;j<=k;j++)a[i][j]=rdn();
  tot=1;build(1,n,1);
  Q=rdn();
  for(int i=1,op,id,l,r;i<=Q;i++)
    {
      op=rdn();
      if(op==1)
	{
	  id=rdn();
	  for(int j=1;j<=k;j++)a[id][j]=rdn();
	  updt(1,n,1,id);
	}
      else
	{
	  l=rdn();r=rdn();
	  Node d=query(1,n,1,l,r);int ans=-INF;
	  for(int i=0;i<lm;i++)
	    ans=Mx(ans,d.mx[i]-d.mn[i]);
	  printf("%d\n",ans);
	}
    }
  return 0;
}