HDU 4819 Mosaic(二次元線分樹区間クエリ+単点更新テンプレート)


The God of sheep dedes to pixelate some picture s(i.e.change them into pictures with mosaic).Here's how he is gonna make it:for each picture、he divides the picture into n x cel.heress.herech ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch ch chand checks theカラーvalues in the L region whose center is specific cel.Assming the maximand minumカラークラフトin the region is A and B repectively,he will replace theカラーバリューthe chencel/flath 2 
Can you help the God of sheep?
InputThe first line contains an integer T(T≦5)indicating the number of test cases.The n T T T T test cases follow. 
Each test case begins with an integer n(5<n<800).The n the follwing n rowws describe the picturto pixelae、where each has n integers representing the orororororororininin色lues.The J J-th intintintintetethe inininininininininininininininininininininininininininininininininininininininininininininininininininininininininaaathe the the the the the the the the aaaaaaath the the the ath the ed 1,000,000,000(10^9) 
After the description of the picture、there is an integer Q(Q≦100000(10^5)))、indicating the number of mosaics. 
The n Q actititionfollw:the i-th row gives the i-th replaccement made bythe God of sheep:xi,yi,Li(1≦xi,yi≦n,1≦LiLi is odd).This means the God of sheep will changethe ffflilililixi(lililixi)lilitytytytytybubububububububububububuxi the the the lililililililililililililililililililixi the aattttmimimimimimimimimimimimimimimimimimimimimimimimimimimimimimimimimiexample,an query(2,3,3)Canas chaging theカラーバリューof the cel at the second row and the third column accocococococococoding to region(1,2)(1,3)(1,4)(2,3)(3,4)(3,2),(3),(3),3),(3,3),3),(3,3)),thethethrererecentinininininininininininininininininincentathththththththinininininininininininininininininininininininincentatotototototototototonese,the,the,thethe,the,the picture are consided. 
Note that the God of sheep will do the replaccement one by in the order given in the input.は、Output For each test case、print a line「Case()t:」(without) 
For each action、print the newカラーオブthe up dated cell.Sample Input
1
3
1 2 3
4 5 6
7 8 9
5
2 2 1
3 2 3
1 1 3
1 2 3
2 2 3
Sample Output
Case #1:
5
6
3
4
6
クイズ:
件名:
n*nの行列をあげます.毎回、点の座標とlを聞きます.この点の座標を中心に、長い幅がlの正方形行列を作ります.行列の最大値と最小値を求めて、その点の値を最大値と最小値の平均値に変更します.
以前は二次元の木の配列しかしたことがありませんでしたが、二次元の線分樹は本当にできませんでした.直接ブログを探してみました.見てから直接彼のブログをコピーしました.二次元線分樹を考え出したのは世界で初めてです.
元ブロガー:http://blog.csdn.net/htt_h/articale/detail/44944039
ps:
強迫症の私は彼のスペースを全部消して、ビットを加算と乗算に変えて、コードを揃えました.
コード:
#include 
#include 
#include 
#include 
using namespace std;
#define maxn 801
#define inf 0x3f3f3f3f
int maxi[maxn*3][maxn*3];
int mini[maxn*3][maxn*3];
int n;
int val;//    
int x,y;//   ,              
int x1,x2,y1,y2;//     
int crx;//               
int cmax,cmin;//             
void buildy(int rx,int ry,int l,int r)//   
{
  if(l==r)//        1
  {
    if(rx==crx)//        1,      ,    
    {
        scanf("%d",&mini[rx][ry]);
        maxi[rx][ry]=mini[rx][ry];
    }
    else//        1,       ,              pushup
    {
        int lrx=rx*2,rrx=rx*2+1;
        maxi[rx][ry]=max(maxi[lrx][ry],maxi[rrx][ry]);
        mini[rx][ry]=min(mini[lrx][ry],mini[rrx][ry]);
    }
    return;
  }
  int m =(l+r)/2;
  int lc=ry*2,rc=ry*2+1;
  buildy(rx,lc,l,m);//     1     
  buildy(rx,rc,m+1,r);
  maxi[rx][ry]=max(maxi[rx][lc],maxi[rx][rc]);//        1,       ,            
  mini[rx][ry]=min(mini[rx][lc],mini[rx][rc]);
}
void buildx(int rx,int l,int r)//   
{
  int m =(l+r)/2;
  if(r>l)//      ,       
  {
    buildx(rx*2,l,m);
    buildx(rx*2+1,m+1,r);
  }
  if(l==r){crx=rx;x=l;}//       1,           ,             
  buildy(rx,1,1,n);//   
}
void updatey(int rx,int ry,int l,int r)//   
{
  if(l==r)//     1
  {
    if(rx==crx)//     1,        
        maxi[rx][ry]=mini[rx][ry]=val;
    else{//       ,           
        int lrx=rx*2,rrx=rx*2+1;
        maxi[rx][ry]=max(maxi[lrx][ry],maxi[rrx][ry]);//        1,      ,         
        mini[rx][ry]=min(mini[lrx][ry],mini[rrx][ry]);
    }
    return;
  }
  int m=(l+r)/2;
  int lc=ry*2,rc=ry*2+1;
  if(y<=m)//    
    updatey(rx,lc,l,m);
  else
    updatey(rx,rc,m+1,r);
  maxi[rx][ry]=max(maxi[rx][lc],maxi[rx][rc]);//        1           
  mini[rx][ry]=min(mini[rx][lc],mini[rx][rc]);
}
void updatex(int rx, int l, int r)//   
{
  int m=(l+r)/2;
  int lc=rx*2,rc=rx*2+1;
  if(r>l)//      1    
  {
    if(x<=m)
        updatex(lc,l,m);
    else
        updatex(rc,m+1,r);
  }
  if(l==r)
    crx=rx;
  updatey(rx,1,1,n);//         
}
void qy(int rx,int ry,int l,int r)//   
{
  if(y1<=l&&y2>=r)//          
  {
    cmin=min(cmin,mini[rx][ry]);
    cmax=max(cmax,maxi[rx][ry]);
    return;
  }

  int m=(l+r)/2;
  int lc=ry*2,rc=ry*2+1;
  if(y1<=m)
    qy(rx,lc,l,m);
  if(y2>m)
    qy(rx,rc,m+1,r);
}

void qx(int rx,int l,int r)//   
{
  if(x1<=l&&x2>=r)//         ,   
  {
    qy(rx,1,1,n);
    return;
  }
  int m =(l+r)/2;
  int lc=rx*2,rc=rx*2+1;
  if(x1<=m)
    qx(lc,l,m);
  if(x2>m)
    qx(rc,m+1,r);
}
int main()
{
  int t,cnt=1;
  scanf("%d",&t);
  while(t--)
 {
    memset(maxi,-inf,sizeof(maxi));
    memset(mini,inf,sizeof(mini));
    printf("Case #%d:
",cnt++); scanf("%d",&n); buildx(1,1,n); int l; int q; scanf("%d",&q); while(q--) { scanf("%d%d%d",&x,&y,&l); l/=2; x1=max(1,x-l);x2=min(n,x+l); y1=max(1,y-l);y2=min(n,y+l); cmax=-inf,cmin=inf;qx(1,1,n);// val=(cmin+cmax)/2; printf("%d
",val); crx=-1;updatex(1,1,n); } } return 0; }