二维线段树 HDU 1823最简单的入门题
xiaoz 征婚,首先输入M,表示有M个操作。
借下来M行,对每一行 Ih a l I 表示有一个MM报名,H是高度, a是活泼度,L是缘分。
或 Q h1 h2 a1 a2 求出身高在h1 h2 活泼度在a1 a2之间的最大缘分值。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <string> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <list> 13 #include <iomanip> 14 #include <cstdlib> 15 #include <sstream> 16 using namespace std; 17 typedef long long LL; 18 const int INF=0x5fffffff; 19 const double EXP=1e-6; 20 const int MS=1001; 21 22 struct active 23 { 24 int l,r; 25 double maxv; 26 int mid() 27 { 28 return (l+r)>>1; 29 } 30 }; 31 32 struct node 33 { 34 int l,r; 35 active actives[4*MS]; 36 int mid() 37 { 38 return (l+r)>>1; 39 } 40 }nodes[405]; 41 42 void init() 43 { 44 for(int i=0;i<405;i++) 45 for(int j=0;j<4*MS;j++) 46 nodes[i].actives[j].maxv=-1; 47 } 48 49 void creat_a(int p,int root,int l,int r) 50 { 51 nodes[p].actives[root].l=l; 52 nodes[p].actives[root].r=r; 53 if(nodes[p].actives[root].l==nodes[p].actives[root].r) 54 return ; 55 int mid=(l+r)/2; 56 creat_a(p,root<<1,l,mid); 57 creat_a(p,root<<1|1,mid+1,r); 58 } 59 60 void creat(int root,int l,int r) 61 { 62 nodes[root].l=l; 63 nodes[root].r=r; 64 creat_a(root,1,0,MS); 65 if(nodes[root].l==nodes[root].r) 66 return ; 67 int mid=(l+r)/2; 68 creat(root<<1,l,mid); 69 creat(root<<1|1,mid+1,r); 70 } 71 72 void insert_a(int p,int root,int pos,double value) 73 { 74 if(nodes[p].actives[root].maxv<value) 75 nodes[p].actives[root].maxv=value; 76 if(nodes[p].actives[root].l==nodes[p].actives[root].r) 77 return ; 78 if(pos<=nodes[p].actives[root].mid()) 79 insert_a(p,root<<1,pos,value); 80 else 81 insert_a(p,root<<1|1,pos,value); 82 } 83 84 void insert(int root,int pos,int value,double s) 85 { 86 insert_a(root,1,value,s); 87 if(nodes[root].l==nodes[root].r) 88 return ; 89 if(pos<=nodes[root].mid()) 90 insert(root<<1,pos,value,s); 91 else 92 insert(root<<1|1,pos,value,s); 93 } 94 95 double query_a(int p,int root,int l,int r) 96 { 97 double ans=-1; 98 if(nodes[p].actives[root].l>=l&&nodes[p].actives[root].r<=r) 99 return nodes[p].actives[root].maxv; 100 if(l<=nodes[p].actives[root].mid()) 101 ans= max(ans,query_a(p,root<<1,l,r)); 102 if(r>nodes[p].actives[root].mid()) 103 ans=max(ans,query_a(p,root<<1|1,l,r)); 104 return ans; 105 } 106 107 double query(int root,int l1,int r1,int l2,int r2) 108 { 109 double ans=-1; 110 if(nodes[root].l>=l1&&nodes[root].r<=r1) 111 return query_a(root,1,l2,r2); 112 // 如果是叶子节点会在上一条语句中返回。 113 if(l1<=nodes[root].mid()) 114 ans=max(ans,query(root<<1,l1,r1,l2,r2)); 115 if(r1>nodes[root].mid()) 116 ans=max(ans,query(root<<1|1,l1,r1,l2,r2)); 117 return ans; 118 } 119 120 int main() 121 { 122 int n,h1,h2; 123 double a1,a2,fate; 124 creat(1,100,200); 125 while(scanf("%d",&n)==1&&n) 126 { 127 init(); 128 char cmd[MS]; 129 while(n--) 130 { 131 scanf("%s",cmd); 132 if(cmd[0]=='I') 133 { 134 scanf("%d %lf %lf",&h1,&a1,&fate); 135 136 insert(1,h1,(int)(a1*10+EXP),fate); 137 } 138 else 139 { 140 scanf("%d %d %lf %lf",&h1,&h2,&a1,&a2); 141 if(h1>h2) 142 swap(h1,h2); 143 if(a1>a2) 144 swap(a1,a2); 145 double ans=query(1,h1,h2,(int)(a1*10+EXP),(int)(a2*10+EXP)); 146 if(ans>=0) 147 printf("%.1lf\n",ans); 148 else 149 printf("-1\n"); 150 } 151 } 152 } 153 return 0; 154 }