标签:onclick 线性 return val 原来 树状 两种 结果 abc
给出一个矩阵,初始每个位置上的值都为0,然后有两种操作
这个结果显示,A’B’C’D’(X,Y)是ABCD(x,y)绕原点(0,0)左旋转45°后的结果,同时长度变为原来的sqrt(2)倍。
由于菱形范围为对角线OA的距离,正方形为一半边长OM的距离,相等,所以无需对距离进行操作。
1,离线离散
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 4000005; const int maxm = 80005; #define lowbit(x) ((x)&(-x)) int N, M, W, E, H[maxn+5], fenw[maxn + 5]; int O[maxm], X[maxm], Y[maxm], Z[maxm]; inline int find (int x) { return lower_bound(H + 1, H + E, x) - H; } void hashPoint (int x, int y) { for (int i = x; i <= W; i += lowbit(i)) { for (int j = y; j <= W; j += lowbit(j)) H[E++] = i * W + j; } } void add(int x, int y, int d) { for (int i = x; i <= W; i += lowbit(i)) { for (int j = y; j <= W; j += lowbit(j)) { int pos = find(i * W + j); fenw[pos] += d; } } } int sum (int x, int y) { int ret = 0; for (int i = x; i; i -= lowbit(i)) { for (int j = y; j; j -= lowbit(j)) { int pos = find(i * W + j); if (H[pos] == i * W + j) ret += fenw[pos]; } } return ret; } void init () { E = 1; W = 2 * N; scanf("%d", &M); memset(fenw, 0, sizeof(fenw)); for (int i = 1; i <= M; i++) { scanf("%d%d%d%d", &O[i], &X[i], &Y[i], &Z[i]); int x = X[i] - Y[i] + N; int y = X[i] + Y[i]; if (O[i] == 1) hashPoint(x, y); } sort(H + 1, H + E); E = unique(H + 1, H + E) - H; } void solve() { for (int i = 1; i <= M; i++) { int x = X[i] - Y[i] + N; int y = X[i] + Y[i]; if (O[i] == 1) add(x, y, Z[i]); else { int a = max(1, x - Z[i]); int b = max(1, y - Z[i]); int c = min(W, x + Z[i]); int d = min(W, y + Z[i]); printf("%d\n", sum(c, d) - sum(c, b-1) - sum(a-1, d) + sum(a-1, b-1)); } } } int main () { while (scanf("%d", &N) == 1 && N) { init(); solve(); } return 0; }
2,线性探测再散列。以前再kbrdhash时用到过,大同小异吧http://www.cnblogs.com/hua-dong/p/7714475.html。
但是不知道为什么炸内存了(别人的代码)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define MAXN 4001003 #define MAXM 88888 using namespace std; int n, m; int W; int h[MAXN]; int a[MAXN]; int hash(int x) { int pos = x % MAXN; while(true) { if(h[pos] == 0 || h[pos] == x) { h[pos] = x; return pos; } pos++; if(pos == MAXN) pos = 0; } } int gethash(int x) { int pos = x % MAXN; while(true) { if(h[pos] == 0 || h[pos] == x) return pos; pos++; if(pos == MAXN) pos = 0; } } inline int lowbit(int x) { return x & -x; } void add(int x, int y, int val) { for(int i = x; i <= W; i += lowbit(i)) for(int j = y; j <= W; j += lowbit(j)) a[hash(i * W + j)] += val; } int getsum(int x, int y) { int sum = 0; for(int i = x; i > 0; i -= lowbit(i)) for(int j = y; j > 0; j -= lowbit(j)) sum += a[gethash(i * W + j)]; return sum; } int main() { int p, x, y, z, xa, xb, ya, yb, newx, newy; while(scanf("%d", &n) != EOF && n) { scanf("%d", &m); W = n * 2; memset(a, 0, sizeof(a)); memset(h, 0, sizeof(h)); for(int i = 0; i < m; i++) { scanf("%d%d%d%d", &p, &x, &y, &z); newx = x - y + n; newy = x + y; if(p == 1) add(newx, newy, z); else { xa = max(1, newx - z); ya = max(1, newy - z); xb = min(W, newx + z); yb = min(W, newy + z); printf("%d\n", getsum(xb, yb) - getsum(xa - 1, yb) - getsum(xb, ya - 1) + getsum(xa - 1, ya - 1)); } } } return 0; }
(类似用到了坐标转化的题:HDU4312)
HDU4456-Crowd (坐标旋转处理+hash处理+二维树状数组)
标签:onclick 线性 return val 原来 树状 两种 结果 abc
原文地址:http://www.cnblogs.com/hua-dong/p/7976753.html