首页 > 代码库 > POJ 1195 2维线段树(树套树实现) 树状数组
POJ 1195 2维线段树(树套树实现) 树状数组
1: #include <stdio.h>
2: #include <string.h>
3: #include <stdlib.h>
4: #include <algorithm>
5: #include <iostream>
6: using namespace std;
7:
8: #define LL(a) a<<1
9: #define RR(a) a<<1|1
10: const int MaxL = 1005;
11: struct sub_Seg_tree_node
12: {
13: int subleft,subright; // ydown = subleft, yup = subright
14: // int maxval; // the maval of the rect x [left,right], y [subleft, subright]
15: int sum; // the sum of the num of point in rect x [left, right], y [subleft, subright]
16: };
17:
18: struct Seg_tree_node
19: {
20: int left,right; // left = xleft, right = xright
21: sub_Seg_tree_node T[MaxL<<2];
22: } TT[MaxL<<2];
23:
24: void sub_build(int subl, int subr, int subidx, int idx)
25: {
26: TT[idx].T[subidx].subleft=subl;
27: TT[idx].T[subidx].subright=subr;
28: // TT[idx].T[subidx].maxval=-1;
29: TT[idx].T[subidx].sum=0;
30: if(subl==subr) return;
31: int mid=(subl+subr)>>1;
32: sub_build(subl, mid, LL(subidx), idx);
33: sub_build(mid+1, subr, RR(subidx), idx);
34: }
35:
36: void build(int l, int r, int subl, int subr, int idx)
37: {
38: TT[idx].left = l, TT[idx].right = r;
39: sub_build(subl, subr, 1, idx);
40: if(l==r) return;
41: int mid=(l+r)>>1;
42: build(l,mid,subl,subr, LL(idx));
43: build(mid+1,r,subl,subr, RR(idx));
44: }
45:
46: void sub_update(int y, int val, int subidx, int idx)
47: {
48: TT[idx].T[subidx].sum += val;
49: // TT[idx].T[subidx].maxval=max(TT[idx].T[subidx].maxval, val);
50: if(TT[idx].T[subidx].subleft == TT[idx].T[subidx].subright) return;
51: int mid=(TT[idx].T[subidx].subleft+TT[idx].T[subidx].subright)>>1;
52: if(y <= mid)
53: sub_update(y, val, LL(subidx), idx);
54: else
55: sub_update(y, val, RR(subidx), idx);
56: }
57:
58: void update(int x, int y, int val, int idx)
59: {
60: sub_update(y, val, 1, idx);
61: if(TT[idx].left == TT[idx].right) return;
62: int mid=(TT[idx].left+TT[idx].right)>>1;
63: if( x<=mid)
64: update(x,y,val, LL(idx) );
65: else
66: update(x,y, val,RR(idx));
67: }
68:
69: //int sub_query(int subl, int subr, int subidx, int idx)
70: //{
71: // if(TT[idx].T[subidx].subleft == subl && TT[idx].T[subidx].subright == subr)
72: // return TT[idx].T[subidx].maxval;
73: // int mid = (TT[idx].T[subidx].subleft + TT[idx].T[subidx].subright)>>1;
74: // if(subr <= mid)
75: // return sub_query(subl, subr, LL(subidx), idx);
76: // else if(subl > mid)
77: // return sub_query(subl, subr, RR(subidx), idx);
78: // else
79: // return max(sub_query(subl, mid, LL(subidx), idx),sub_query(mid+1, subr, RR(subidx), idx));
80: //}
81: //
82: //int query(int l, int r, int subl, int subr, int idx)
83: //{
84: // if(TT[idx].left == l && TT[idx].right == r)
85: // return sub_query(subl, subr, 1, idx);
86: // int mid = (TT[idx].left + TT[idx].right)>>1;
87: // if(r <= mid)
88: // return query(l,r, subl,subr, LL(idx));
89: // else if(l > mid)
90: // return query(l, r, subl, subr, RR(idx));
91: // else
92: // return max(query(l, mid, subl, subr, LL(idx)),query(mid+1, r, subl,subr, RR(idx)));
93: //}
94:
95: int sub_query(int subl, int subr, int subidx, int idx)
96: {
97: if(TT[idx].T[subidx].subleft == subl && TT[idx].T[subidx].subright == subr)
98: return TT[idx].T[subidx].sum;
99: int mid = (TT[idx].T[subidx].subleft + TT[idx].T[subidx].subright)>>1;
100: if(subr <= mid)
101: return sub_query(subl, subr, LL(subidx), idx);
102: else if(subl > mid)
103: return sub_query(subl, subr, RR(subidx), idx);
104: else
105: return sub_query(subl, mid, LL(subidx), idx) + sub_query(mid+1, subr, RR(subidx), idx);
106: }
107:
108: int query(int l, int r, int subl, int subr, int idx)
109: {
110: if(TT[idx].left == l && TT[idx].right == r)
111: return sub_query(subl, subr, 1, idx);
112: int mid = (TT[idx].left + TT[idx].right)>>1;
113: if(r <= mid)
114: return query(l,r, subl,subr, LL(idx));
115: else if(l > mid)
116: return query(l, r, subl, subr, RR(idx));
117: else
118: return query(l, mid, subl, subr, LL(idx))+ query(mid+1, r, subl,subr, RR(idx));
119: }
120:
121: int x1[10005];
122: int y1[10005];
123: int x2[10005];
124: int y2[10005];
125: int px[10005];
126: int py[10005];
127: int pval[10005];
128: //
129: //int main()
130: //{
131: // freopen("1.txt","r",stdin);
132: // int NN,MM;
133: // cin>>NN>>MM;
134: //
135: // for(int i=0; i<NN; i++)
136: // scanf("%d%d%d", &px[i],&py[i], &pval[i]);
137: //
138: // for(int i=0; i<MM; i++)
139: // {
140: // scanf("%d%d%d%d", &x1[i], &y1[i], &x2[i], &y2[i]);
141: // if(x1[i] > x2[i]) swap(x1[i], x2[i]);
142: // if(y1[i] > y2[i]) swap(y1[i], y2[i]);
143: // }
144: //
145: // build(0, 1060, 0, 1060, 1);
146: // for(int i=0; i<NN; i++)
147: // {
148: // cout<<"update point "<<px[i]<<" "<<py[i]<<endl;
149: // update(px[i],py[i],pval[i], 1);
150: // }
151: //
152: // for(int i=0; i<MM; i++)
153: // {
154: // cout<<"query ret "<<x1[i]<<" "<<x2[i]<<" "<<y1[i]<<" "<<y2[i]<<endl;
155: // cout<<"Ret "<<query(x1[i],x2[i],y1[i],y2[i],1)<<endl;
156: // }
157: //
158: // return 0;
159: //}
160: int s;
161: int main()
162: {
163: // freopen("1.txt","r",stdin);
164: int i;
165: int sb;
166: int sb1,sb2,sb3,sb4;
167: scanf("%d",&sb);
168: while(sb!=3)
169: {
170: switch(sb)
171: {
172: case 0:
173: scanf("%d",&s);
174: build(0,s,0,s,1);
175: break;
176: case 1:
177: scanf("%d%d%d",&sb1,&sb2,&sb3);
178: update(sb1,sb2,sb3,1);
179: break;
180: case 2:
181: scanf("%d%d%d%d",&sb1,&sb2,&sb3,&sb4);
182: printf("%d\n",query(sb1,sb3,sb2,sb4,1));
183: break;
184: default:
185: goto ed;
186: }
187: scanf("%d",&sb);
188: }
189: ed:
190: ;
191: return 0;
192: }
树状数组来做这个题目相对来说简单得多! 树状数组则清楚得多.相对来说二维线段树用得比较少,而且功能都比较简单,查询平面矩形包含几个点,查询矩形最大值之类的.
1: #include <iostream>
2: #include <stdio.h>
3: #include <string.h>
4: using namespace std;
5:
6: #define MAX 1026
7: int s[MAX][MAX];
8: int lowbit(int x)
9: {
10: return x&(x^(x-1));
11: }
12:
13: int N;
14:
15: void change(int a,int b,int delta)
16: {
17: for(int x=a; x<=N; x+=lowbit(x))
18: for(int y=b; y<=N; y+=lowbit(y))
19: s[x][y]+=delta;
20: }
21: int sum(int a,int b)
22: {
23: int res=0;
24: for(int x=a; x>0; x-=lowbit(x))
25: for(int y=b; y>0; y-=lowbit(y))
26: res+=s[x][y];
27: return res;
28: }
29: int main()
30: {
31: int n;
32: while(cin>>n)
33: {
34: if(n==0)
35: {
36: cin>>N; N++;
37: memset(s,0,sizeof(s));
38: }
39: else if(n==1)
40: {
41: int a,b,c;
42: cin>>a>>b>>c; a++; b++;
43: change(a,b,c);
44: }
45: else if(n==2)
46: {
47: int a,b,c,d;
48: cin>>a>>b>>c>>d;
49: a++;b++;c++;d++;
50: cout<<sum(c,d) + sum(a-1,b-1) - sum(a-1,d) - sum(c,b-1)<<endl;
51: }
52: else break;;
53: }
54: return 0;
55: }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。