題目大意:給你n個點, n個點的座標都在200之內,讓你統計不相交的兩個L形的種數,且L形的兩條邊長的gcd = 1。c++
思路:用二維樹狀數組維護點的信息,而後劃分區塊進行統計,題解是用總的減去相交的,不須要用到二維樹狀數組。數組
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> using namespace std; const int N = 200 + 7; const int M = 1e4 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; const double eps=1e-6; const double pi=acos(-1); int n, m, up[N][N], rt[N][N]; LL cnt[N][N], num[N][N]; bool Map[N][N]; struct BIT { LL a[N][N]; void modify(int x, int y, LL v) { for(int i = x; i < N; i += i & -i) for(int j = y; j < N; j += j & -j) a[i][j] += v; } LL sum(int x, int y) { LL ans = 0; for(int i = x; i; i -= i & -i) for(int j = y; j; j -= j & -j) ans += a[i][j]; return ans; } void init() { memset(a, 0, sizeof(a)); } }bit1, bit2; void init() { for(int i = 1; i < N; i++) { for(int j = 1; j < N; j++) { cnt[i][j] = cnt[i][j - 1] + (__gcd(i, j) == 1); } } for(int i = 1; i < N; i++) { for(int j = 1; j < N; j++) { for(int k = 1; k <= i; k++) { num[i][j] += cnt[k][j]; } } } } int main() { init(); int T; scanf("%d", &T); for(int cas = 1; cas <= T; cas++) { bit1.init(); bit2.init(); memset(rt, 0, sizeof(rt)); memset(up, 0, sizeof(up)); memset(Map, 0, sizeof(Map)); scanf("%d", &n); for(int i = 1; i <= n; i++) { int x, y; scanf("%d%d", &x, &y); Map[x][y] = true; } for(int i = 200; i >= 1; i--) { for(int j = 200; j >= 1; j--) { if(Map[i][j]) { up[i][j] = up[i + 1][j] + 1; rt[i][j] = rt[i][j + 1] + 1; } } } LL ans = 0; for(int i = 200; i >= 1; i--) { for(int j = 1; j <= 200; j++) { if(!Map[i][j] || up[i][j] <= 1 || rt[i][j] <= 1) continue; ans += num[up[i][j] - 1][rt[i][j] - 1] * (bit2.sum(200, 200) - bit2.sum(i + up[i][j] - 1, j)); int q = i + up[i][j] - 1; for(int k = i + 1; k <= 200 && k <= q; k++) { ans += cnt[k - i][rt[i][j] - 1] * (bit2.sum(q, j) - bit2.sum(k, j)); ans += cnt[k - i][rt[i][j] - 1] * (bit1.sum(k, j - 1)); } bit2.modify(i, j, num[up[i][j] - 1][rt[i][j] - 1]); for(int k = j + 1; k <= 200 && k < j + rt[i][j]; k++) { bit1.modify(i, k, cnt[k - j][up[i][j] - 1]); } } } printf("Case #%d: %lld\n", cas, 2 * ans); } return 0; } /* */