hdu 4819 二维线段树点更新
来源:互联网 发布:淘宝非法交易如何退货 编辑:程序博客网 时间:2024/05/22 07:57
题意:
算一个子矩形内的最大和最小的平均值,并将该平均值更新到该子矩形的中心(该矩形的边为奇数)
解题思路:
利用二维线段树的点更新和query即可
注意:
二维线段树的在点更新时,需先更新局部的子区间,然后更新全局区间
//原版#include <stdio.h>#include <string.h>#include <stdlib.h>#define MAXN0 801#define INF 1<<30int max(int aa,int bb);int min(int aa,int bb);struct node1{ int yL,yR; int minV,maxV; void setLR(int aa,int bb){ yL = aa; yR = bb; //minV = cc; //maxV = dd; } void setVV(int aa,int bb){ minV = min(aa,bb); maxV = max(aa,bb); } bool equal(int aa,int bb){ if(yL==aa&&yR==bb){ return true; } return false; } };struct node2{ int xL,xR; void set(int aa,int bb){ xL = aa; xR = bb; } node1 subTR[MAXN0<<2];};node2 TR[MAXN0<<2];int mat[MAXN0][MAXN0];int maxF,minF;int max(int aa,int bb){ return aa>bb?aa:bb;}int min(int aa,int bb){ return aa<bb?aa:bb;}void buildsubTR(int ind1,int ind2,int L,int R){ TR[ind1].subTR[ind2].setLR(L, R); TR[ind1].subTR[ind2].maxV =0; TR[ind1].subTR[ind2].minV = INF; if(L==R){ //TR[ind1].subTR[ind2].setVV(mat[TR[ind1].xR][R],mat[TR[ind1].xR][R]); return; } int mid = (L+R)>>1; buildsubTR(ind1,ind2<<1,L,mid); buildsubTR(ind1, (ind2<<1)+1, mid+1,R); // TR[ind1].subTR[ind2].minV = min(TR[ind1].subTR[ind2<<1].minV, TR[ind1].subTR[(ind2<<1)+1].minV); // TR[ind1].subTR[ind2].maxV = max(TR[ind1].subTR[ind2<<1].maxV, TR[ind1].subTR[(ind2<<1)+1].maxV);}void buildTR(int ind,int L,int R,int L1,int R1){ TR[ind].set(L, R); buildsubTR(ind, 1, L1,R1); if(L==R){ // buildsubTR(ind, 1, L1,R1); return; } int mid = (L+R)>>1; buildTR(ind<<1,L,mid,L1,R1); buildTR((ind<<1)+1,mid+1,R,L1,R1); TR[ind].subTR[1].minV = min(TR[ind<<1].subTR[1].minV, TR[(ind<<1)+1].subTR[1].minV); TR[ind].subTR[1].maxV = max(TR[ind<<1].subTR[1].maxV, TR[(ind<<1)+1].subTR[1].maxV); }void Querysub(int ind1,int ind2,int L2,int R2){ if(TR[ind1].subTR[ind2].equal(L2,R2)){ minF = min(minF,TR[ind1].subTR[ind2].minV); maxF = max(maxF,TR[ind1].subTR[ind2].maxV); return; } //int mid; if(TR[ind1].subTR[ind2].yL!=TR[ind1].subTR[ind2].yR){ int mid = (TR[ind1].subTR[ind2].yL+TR[ind1].subTR[ind2].yR)>>1; if(mid>=R2){ Querysub(ind1, ind2<<1, L2, R2); } else if(mid<L2){ Querysub(ind1, (ind2<<1)+1, L2, R2); } else { Querysub(ind1, ind2<<1, L2, mid); Querysub(ind1, (ind2<<1)+1, mid+1, R2); } }}void Query(int ind1,int L1,int R1,int L2,int R2){ if(TR[ind1].xL==L1&&TR[ind1].xR==R1){ Querysub(ind1,1,L2,R2); return; } if(TR[ind1].xL!=TR[ind1].xR){ int mid = (TR[ind1].xL+TR[ind1].xR)>>1; if(mid>=R1){ Query(ind1<<1, L1, R1, L2,R2); } else if(mid<L1){ Query((ind1<<1)+1,L1,R1,L2,R2); } else { Query(ind1<<1, L1, mid, L2, R2); Query((ind1<<1)+1, mid+1, R1, L2, R2); } }}void updatesub(int ind1,int ind2,int x,int y,int upd){ if(TR[ind1].subTR[ind2].equal(y,y)){ if(TR[ind1].xL==TR[ind1].xR){ TR[ind1].subTR[ind2].setVV(upd, upd); } else { TR[ind1].subTR[ind2].minV = min(TR[(ind1<<1)+1].subTR[(ind2)].minV,TR[ind1<<1].subTR[(ind2)].minV); TR[ind1].subTR[ind2].maxV = max(TR[ind1<<1].subTR[(ind2)].maxV, TR[(ind1<<1)+1].subTR[(ind2)].maxV); } return; } int mid = (TR[ind1].subTR[ind2].yL+TR[ind1].subTR[ind2].yR)>>1; if(mid>=y){ updatesub(ind1, ind2<<1, x,y, upd); } else{ updatesub(ind1, (ind2<<1)+1, x, y, upd); } TR[ind1].subTR[ind2].minV = min(TR[ind1].subTR[ind2<<1].minV, TR[ind1].subTR[(ind2<<1)+1].minV); TR[ind1].subTR[ind2].maxV = max(TR[ind1].subTR[ind2<<1].maxV, TR[ind1].subTR[(ind2<<1)+1].maxV); }void update(int ind1,int x,int y,int upd){ if(TR[ind1].xL==x&&TR[ind1].xR==x){ updatesub(ind1, 1,x, y, upd); return; } int mid = (TR[ind1].xL+TR[ind1].xR)>>1; if(mid>=x){ update(ind1<<1, x, y, upd); } else { update((ind1<<1)+1, x, y, upd); } updatesub(ind1, 1, x,y, upd); TR[ind1].subTR[1].minV = min(TR[ind1<<1].subTR[1].minV, TR[(ind1<<1)+1].subTR[1].minV); TR[ind1].subTR[1].maxV = max(TR[ind1<<1].subTR[1].maxV, TR[(ind1<<1)+1].subTR[1].maxV);}void prepro(int n){ // for(int i=1;i<=n;++i){ // for(int j=1;j<=n;++j){ // if(j==1){ // minmat[j][i] = maxmat[j][i] = mat[j][i]; // } // else{ // minmat[j][i] = min(minmat[j-1][i],); // } // } // }}int main(){ int T,n,Q,xi,yi,Li,L1,R1,L2,R2,tmp,ans; int cas = 0; scanf("%d",&T); while(T--){ scanf("%d",&n); buildTR(1,1,n,1,n); for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ scanf("%d",&mat[i][j]); update(1, i, j, mat[i][j]); } } //prepro(n); printf("Case #%d:\n",++cas); scanf("%d",&Q); while(Q--){ scanf("%d%d%d",&xi,&yi,&Li); tmp = Li/2; L1 = xi - tmp; if(L1<=0)L1 = 1; R1 = xi + tmp; if(R1>n)R1 = n; L2 = yi - tmp; if(L2<=0)L2 = 1; R2 = yi+tmp; if(R2>n)R2 = n; maxF = 0; minF = INF; Query(1,L1,R1,L2,R2); ans = (maxF+minF)/2; printf("%d\n",ans); if(mat[xi][yi]!=ans){ update(1,xi,yi,ans); mat[xi][yi] = ans; } } } return 0;}//改进//总结:且先解决子问题,然后总问题即可解决#include <stdio.h>#include <string.h>#include <stdlib.h>#define MAXN0 801#define INF 1<<30int max(int aa,int bb);int min(int aa,int bb);struct node1{ int yL,yR; int minV,maxV; void setLR(int aa,int bb){ yL = aa; yR = bb; //minV = cc; //maxV = dd; } void setVV(int aa,int bb){ minV = min(aa,bb); maxV = max(aa,bb); } bool equal(int aa,int bb){ if(yL==aa&&yR==bb){ return true; } return false; } };struct node2{ int xL,xR; void set(int aa,int bb){ xL = aa; xR = bb; } node1 subTR[MAXN0<<2];};node2 TR[MAXN0<<2];int mat[MAXN0][MAXN0];int maxF,minF;int max(int aa,int bb){ return aa>bb?aa:bb;}int min(int aa,int bb){ return aa<bb?aa:bb;}void buildsubTR(int ind1,int ind2,int L,int R){ TR[ind1].subTR[ind2].setLR(L, R); // TR[ind1].subTR[ind2].maxV =0; // TR[ind1].subTR[ind2].minV = INF; if(L==R){ if(TR[ind1].xR==TR[ind1].xL){ TR[ind1].subTR[ind2].setVV(mat[TR[ind1].xR][R],mat[TR[ind1].xR][R]); } else { TR[ind1].subTR[ind2].minV = min(TR[(ind1<<1)+1].subTR[(ind2)].minV,TR[ind1<<1].subTR[(ind2)].minV); TR[ind1].subTR[ind2].maxV = max(TR[ind1<<1].subTR[(ind2)].maxV, TR[(ind1<<1)+1].subTR[(ind2)].maxV); } return; } int mid = (L+R)>>1; buildsubTR(ind1,ind2<<1,L,mid); buildsubTR(ind1, (ind2<<1)+1, mid+1,R); TR[ind1].subTR[ind2].minV = min(TR[ind1].subTR[ind2<<1].minV, TR[ind1].subTR[(ind2<<1)+1].minV); TR[ind1].subTR[ind2].maxV = max(TR[ind1].subTR[ind2<<1].maxV, TR[ind1].subTR[(ind2<<1)+1].maxV);}void buildTR(int ind,int L,int R,int L1,int R1){ TR[ind].set(L, R); //buildsubTR(ind, 1, L1,R1); if(L==R){ buildsubTR(ind, 1, L1,R1); return; } int mid = (L+R)>>1; buildTR(ind<<1,L,mid,L1,R1); buildTR((ind<<1)+1,mid+1,R,L1,R1); buildsubTR(ind, 1, L1,R1); TR[ind].subTR[1].minV = min(TR[ind<<1].subTR[1].minV, TR[(ind<<1)+1].subTR[1].minV); TR[ind].subTR[1].maxV = max(TR[ind<<1].subTR[1].maxV, TR[(ind<<1)+1].subTR[1].maxV); }void Querysub(int ind1,int ind2,int L2,int R2){ if(TR[ind1].subTR[ind2].equal(L2,R2)){ minF = min(minF,TR[ind1].subTR[ind2].minV); maxF = max(maxF,TR[ind1].subTR[ind2].maxV); return; } //int mid; if(TR[ind1].subTR[ind2].yL!=TR[ind1].subTR[ind2].yR){ int mid = (TR[ind1].subTR[ind2].yL+TR[ind1].subTR[ind2].yR)>>1; if(mid>=R2){ Querysub(ind1, ind2<<1, L2, R2); } else if(mid<L2){ Querysub(ind1, (ind2<<1)+1, L2, R2); } else { Querysub(ind1, ind2<<1, L2, mid); Querysub(ind1, (ind2<<1)+1, mid+1, R2); } }}void Query(int ind1,int L1,int R1,int L2,int R2){ if(TR[ind1].xL==L1&&TR[ind1].xR==R1){ Querysub(ind1,1,L2,R2); return; } if(TR[ind1].xL!=TR[ind1].xR){ int mid = (TR[ind1].xL+TR[ind1].xR)>>1; if(mid>=R1){ Query(ind1<<1, L1, R1, L2,R2); } else if(mid<L1){ Query((ind1<<1)+1,L1,R1,L2,R2); } else { Query(ind1<<1, L1, mid, L2, R2); Query((ind1<<1)+1, mid+1, R1, L2, R2); } }}void updatesub(int ind1,int ind2,int x,int y,int upd){ if(TR[ind1].subTR[ind2].equal(y,y)){ if(TR[ind1].xL==TR[ind1].xR){ TR[ind1].subTR[ind2].setVV(upd, upd); } else { TR[ind1].subTR[ind2].minV = min(TR[(ind1<<1)+1].subTR[(ind2)].minV,TR[ind1<<1].subTR[(ind2)].minV); TR[ind1].subTR[ind2].maxV = max(TR[ind1<<1].subTR[(ind2)].maxV, TR[(ind1<<1)+1].subTR[(ind2)].maxV); } return; } int mid = (TR[ind1].subTR[ind2].yL+TR[ind1].subTR[ind2].yR)>>1; if(mid>=y){ updatesub(ind1, ind2<<1, x,y, upd); } else{ updatesub(ind1, (ind2<<1)+1, x, y, upd); } TR[ind1].subTR[ind2].minV = min(TR[ind1].subTR[ind2<<1].minV, TR[ind1].subTR[(ind2<<1)+1].minV); TR[ind1].subTR[ind2].maxV = max(TR[ind1].subTR[ind2<<1].maxV, TR[ind1].subTR[(ind2<<1)+1].maxV); }void update(int ind1,int x,int y,int upd){ if(TR[ind1].xL==x&&TR[ind1].xR==x){ updatesub(ind1, 1,x, y, upd); return; } int mid = (TR[ind1].xL+TR[ind1].xR)>>1; if(mid>=x){ update(ind1<<1, x, y, upd); } else { update((ind1<<1)+1, x, y, upd); } updatesub(ind1, 1, x,y, upd); TR[ind1].subTR[1].minV = min(TR[ind1<<1].subTR[1].minV, TR[(ind1<<1)+1].subTR[1].minV); TR[ind1].subTR[1].maxV = max(TR[ind1<<1].subTR[1].maxV, TR[(ind1<<1)+1].subTR[1].maxV);}void prepro(int n){ // for(int i=1;i<=n;++i){ // for(int j=1;j<=n;++j){ // if(j==1){ // minmat[j][i] = maxmat[j][i] = mat[j][i]; // } // else{ // minmat[j][i] = min(minmat[j-1][i],); // } // } // }}int main(){ int T,n,Q,xi,yi,Li,L1,R1,L2,R2,tmp,ans; int cas = 0; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ scanf("%d",&mat[i][j]); // update(1, i, j, mat[i][j]); } } buildTR(1,1,n,1,n); //prepro(n); printf("Case #%d:\n",++cas); scanf("%d",&Q); while(Q--){ scanf("%d%d%d",&xi,&yi,&Li); tmp = Li/2; L1 = xi - tmp; if(L1<=0)L1 = 1; R1 = xi + tmp; if(R1>n)R1 = n; L2 = yi - tmp; if(L2<=0)L2 = 1; R2 = yi+tmp; if(R2>n)R2 = n; maxF = 0; minF = INF; Query(1,L1,R1,L2,R2); ans = (maxF+minF)/2; printf("%d\n",ans); if(mat[xi][yi]!=ans){ update(1,xi,yi,ans); mat[xi][yi] = ans; } } } return 0;}
0 0
- hdu 4819 二维线段树点更新
- hdu 1823 二维线段树点更新
- HDU 4819:单点更新,区间查询的二维线段树
- HDU 4819 Mosaic(二维线段树+单点更新)
- HDU 4819 二维线段树
- HDU 4819 二维线段树
- HDU 4819 二维线段树
- HDU 4819 二维线段树
- hdu 4819 二维线段树
- hdu 2795 线段树--点更新
- hdu 2795 Billboard 线段树 点更新
- HDU 1166 线段树(点更新)
- HDU 4819 Mosaic(二维线段树区间查询+单点更新模板)
- HDU 4819 Mosaic(二维线段树单点更新+区间查询+自己的写法模板)
- hdu 4819 Mosaic (二维线段树)
- HDU-4819-Mosaic(二维线段树)
- HDU 4819 Mosaic 二维线段树
- HDU 4819 Mosaic(二维线段树)
- IEEE会员
- 写一个类似iPhone内置拨号盘上的号码显示Label
- 二分图最大匹配总结
- poj 2472 106 miles to Chicago
- hdu 1698 线段树区间更新
- hdu 4819 二维线段树点更新
- POJ 2236 Wireless Network
- 背包问题 ——第K优解 或 次优解
- UVA 575-Skew Binary
- LeetCode 024. Swap Nodes in Pairs
- hdu1114Piggy-Bank
- 打印二叉树中所有和为某一值的路径
- 二叉树的递归定义及存储
- leetcode:Maximum Subarray---python