HDU 4605 Magic Ball Game(离线算法)
思路就很难想+代码实现也很麻烦,知道算法后,已经写的很繁琐而且花了很长时间,200+,好久没写过这么长的代码了。
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <map> 6 #include <ctime> 7 #include <cmath> 8 #include <algorithm> 9 using namespace std; 10 #define maxn 100101 11 struct node 12 { 13 int l,r; 14 } tree[maxn]; 15 struct nodez 16 { 17 int u,v,next; 18 } edge[100101]; 19 int w[maxn]; 20 int n; 21 int pl[maxn]; 22 int pr[maxn]; 23 int que[maxn]; 24 int qu[maxn],qv[maxn]; 25 int o[maxn]; 26 int ww[maxn],num; 27 int ans1[maxn],ans2[maxn]; 28 int tot; 29 int first[101101]; 30 void CL() 31 { 32 tot = 1; 33 memset(o,0,sizeof(o)); 34 memset(first,-1,sizeof(first)); 35 memset(pl,0,sizeof(pl)); 36 memset(pr,0,sizeof(pr)); 37 } 38 int lowbit(int t) 39 { 40 return t&(-t); 41 } 42 void insert1(int t,int d) 43 { 44 while(t <= n) 45 { 46 pl[t] += d; 47 t += lowbit(t); 48 } 49 } 50 void insert2(int t,int d) 51 { 52 while(t <= n) 53 { 54 pr[t] += d; 55 t += lowbit(t); 56 } 57 } 58 int getsum1(int t) 59 { 60 int sum = 0; 61 while(t) 62 { 63 sum += pl[t]; 64 t -= lowbit(t); 65 } 66 return sum; 67 } 68 int getsum2(int t) 69 { 70 int sum = 0; 71 while(t) 72 { 73 sum += pr[t]; 74 t -= lowbit(t); 75 } 76 return sum; 77 } 78 int bin(int x) 79 { 80 int str,end,mid; 81 str = 1; 82 end = num; 83 while(str < end) 84 { 85 mid = (str+end)/2; 86 if(w[mid] < x) 87 str = mid + 1; 88 else 89 end = mid; 90 } 91 return str; 92 } 93 void add(int u,int v) 94 { 95 edge[tot].u = u; 96 edge[tot].v = v; 97 edge[tot].next = first[u]; 98 first[u] = tot ++; 99 } 100 void dfs(int x) 101 { 102 int sp,s1,s2,s3,s4,s5,s6,i,v; 103 if(o[x]) 104 { 105 for(i = first[x]; i != -1; i = edge[i].next) 106 { 107 v = edge[i].v; 108 if(x == 1) 109 { 110 ans1[v] = 0; 111 ans2[v] = 0; 112 } 113 else 114 { 115 if(qv[v] > w[num]) 116 { 117 s1 = s2 = getsum1(n); 118 s5 = 0; 119 s3 = s4 = getsum2(n); 120 s6 = 0; 121 sp = n; 122 } 123 else if(qv[v] < w[1]) 124 { 125 s1 = s2 = s3 = s4 = 0; 126 s5 = getsum1(n); 127 s6 = getsum2(n); 128 sp = n; 129 } 130 else 131 { 132 sp = bin(qv[v]); 133 s1 = getsum1(sp-1); 134 s2 = getsum1(sp); 135 s3 = getsum2(sp-1); 136 s4 = getsum2(sp); 137 s5 = getsum1(n) - s1; 138 s6 = getsum2(n) - s3; 139 } 140 if(w[sp] == qv[v]&&s2 - s1 > 0) 141 { 142 ans1[v] = -1; 143 ans2[v] = 0; 144 } 145 else if(w[sp] == qv[v]&&s4 - s3 > 0) 146 { 147 ans1[v] = -1; 148 ans2[v] = 0; 149 } 150 else 151 { 152 ans1[v] = s3; 153 ans2[v] = s3*3 + s6 + s1*3 + s5; 154 } 155 } 156 } 157 } 158 if(tree[x].l != -1) 159 { 160 int nu; 161 nu = bin(ww[x]); 162 insert1(nu,1); 163 dfs(tree[x].l); 164 insert1(nu,-1); 165 insert2(nu,1); 166 dfs(tree[x].r); 167 insert2(nu,-1); 168 } 169 return ; 170 } 171 int main() 172 { 173 int i,m,t,fa,ls,rs; 174 scanf("%d",&t); 175 while(t--) 176 { 177 scanf("%d",&n); 178 CL(); 179 for(i = 1; i <= n; i ++) 180 { 181 scanf("%d",&w[i]); 182 ww[i] = w[i]; 183 } 184 for(i = 1; i <= n; i ++) 185 { 186 tree[i].l = tree[i].r = -1; 187 } 188 sort(w+1,w+n+1); 189 num = 1; 190 for(i = 2; i <= n; i ++) 191 { 192 if(w[num] != w[i]) 193 w[++num] = w[i]; 194 } 195 scanf("%d",&m); 196 for(i = 0; i < m; i ++) 197 { 198 scanf("%d%d%d",&fa,&ls,&rs); 199 tree[fa].l = ls; 200 tree[fa].r = rs; 201 } 202 scanf("%d",&m); 203 for(i = 1; i <= m; i ++) 204 { 205 scanf("%d%d",&qu[i],&qv[i]); 206 add(qu[i],i); 207 o[qu[i]] = 1; 208 } 209 dfs(1); 210 for(i = 1; i <= m; i ++) 211 { 212 if(ans1[i] == -1) 213 printf("0\n"); 214 else 215 printf("%d %d\n",ans1[i],ans2[i]); 216 } 217 } 218 return 0; 219 }