A,B两个水题。
C:BFS求最短路,由于范围很大(1e9),而且实际的可走范围比较小,所以需要存储映射关系,类似稀疏矩阵的三元组
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <map> 5 #include <utility> 6 #include <queue> 7 #define LL long long 8 9 using namespace std; 10 11 int dx[] = {0, 0, 1, -1, 1, -1, 1, -1}; 12 int dy[] = {1, -1, 0, 0, 1, -1, -1, 1}; 13 typedef pair<int, int> P; 14 map<P, int> q; 15 struct node 16 { 17 int x, y, l; 18 }; 19 queue<node> qu; 20 int x1, y1, x2, y2; 21 int bfs() 22 { 23 while(!qu.empty()) qu.pop(); 24 node tmp = {x1, y1, 0}; 25 qu.push(tmp); 26 while(!qu.empty()) 27 { 28 tmp = qu.front(); 29 qu.pop(); 30 if(tmp.x == x2 && tmp.y == y2) return tmp.l; 31 for(int i = 0; i < 8; ++i) 32 { 33 P t = make_pair(tmp.x + dx[i], tmp.y + dy[i]); 34 if(q[t] == 1) 35 { 36 q[t] = -1; 37 node nw = {tmp.x + dx[i], tmp.y + dy[i], tmp.l + 1}; 38 qu.push(nw); 39 } 40 } 41 } 42 return -1; 43 } 44 int main() 45 { 46 int n; 47 while(scanf("%d%d%d%d", &x1, &y1, &x2, &y2) == 4) 48 { 49 q.clear(); 50 q[make_pair(x1, y1)] = 1; 51 q[make_pair(x2, y2)] = 1; 52 int m, x, y, z; 53 scanf("%d", &m); 54 while(m--) 55 { 56 scanf("%d%d%d", &x, &y, &z); 57 for(int i = y; i <= z; ++i) 58 q[make_pair(x, i)] = 1; 59 } 60 int ans = bfs(); 61 printf("%d\n", ans); 62 } 63 return 0; 64 }
D:
E:线段树,区间求和,问题是更新时将区间内每个数异或x,可以按位统计二进制1的个数,注意pushdown的写法。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <map> 5 #include <utility> 6 #include <queue> 7 #define LL long long 8 9 using namespace std; 10 11 struct tree 12 { 13 int x; 14 int d[20]; 15 }t[100010 << 2]; 16 int p[20]; 17 void pushdown(int rt, int l, int r) 18 { 19 if(t[rt].x) 20 { 21 t[rt << 1].x ^= t[rt].x; 22 t[rt << 1 | 1].x ^= t[rt].x; 23 int m = (r - l + 1); 24 int left = m - (m >> 1); 25 int right = (m >> 1); 26 for(int i = 0; i < 20; ++i) 27 { 28 if(t[rt].x & (1 << i)) 29 { 30 t[rt << 1].d[i] = (left - t[rt << 1].d[i]); 31 } 32 if(t[rt].x & (1 << i)) 33 { 34 t[rt << 1 | 1].d[i] = (right - t[rt << 1 | 1].d[i]); 35 } 36 } 37 t[rt].x = 0; 38 } 39 } 40 void pushup(int rt) 41 { 42 for(int i = 0; i < 20; ++i) 43 { 44 t[rt].d[i] = t[rt << 1 | 1].d[i] + t[rt << 1].d[i]; 45 } 46 } 47 void update(int l, int r, int rt, int L, int R, int x) 48 { 49 if(L <= l && r <= R) 50 { 51 t[rt].x ^= x; 52 for(int i = 0; i < 20; ++i) 53 { 54 if((1 << i) & x) 55 { 56 t[rt].d[i] = (r - l + 1 - t[rt].d[i]); 57 } 58 } 59 return; 60 } 61 int m = (l + r) >> 1; 62 pushdown(rt, l, r); 63 if(m >= L) update(l, m, rt << 1, L, R, x); 64 if(m < R) update(m + 1, r, rt << 1 | 1, L, R, x); 65 pushup(rt); 66 } 67 68 LL query(int l, int r, int rt, int L, int R) 69 { 70 if(L <= l && r <= R) 71 { 72 LL tmp = 0; 73 for(int i = 0; i < 20; ++i) 74 { 75 tmp += t[rt].d[i] * (LL)p[i]; 76 } 77 return tmp; 78 } 79 LL ans = 0; 80 int m = (l + r) >> 1; 81 pushdown(rt, l, r); 82 if(L <= m) ans += query(l, m, rt << 1, L, R); 83 if(m < R) ans += query(m + 1, r, rt << 1 | 1, L, R); 84 return ans; 85 } 86 87 int main() 88 { 89 int n, m; 90 for(int i = 0; i < 20; ++i) 91 { 92 if(i == 0) p[i] = 1; 93 else p[i] = 2 * p[i - 1]; 94 } 95 scanf("%d", &n); 96 for(int i = 0, x; i < n; ++i) 97 { 98 scanf("%d", &x); 99 update(1, n, 1, i + 1, i + 1, x); 100 } 101 scanf("%d", &m); 102 while(m--) 103 { 104 int x, y, f; 105 scanf("%d%d%d", &f, &x, &y); 106 if(f == 1) 107 { 108 LL ans = 0; 109 ans = query(1, n, 1, x, y); 110 printf("%lld\n", ans); 111 } 112 else 113 { 114 scanf("%d", &f); 115 update(1, n, 1, x, y, f); 116 } 117 } 118 return 0; 119 }