C - Pizza Cutter Gym - 101908C
阿新 • • 發佈:2018-11-17
傳送門:QAQ
題意:給你一個矩形,給你幾條線,問你矩形被分成了多少區域。
思路:離散化一下後,就是經典的樹狀陣列求逆序數,離散化真好,注意會爆(int)。
附上程式碼:
#include<stdio.h> #include<algorithm> #include<cstring> #include<cstdlib> #include<vector> #include<queue> using namespace std; #define inf 0x3f3f3f3f struct inst { int x; int y; }; int srt[110000]; int cx[1100000]; inst ax[110000]; const int maxn = 110000; int n; long long c[maxn], a[maxn]; int lowbit(int x) { return (x)&(-x); } void update_onepos(int pos, int x) { while (pos <= maxn) { c[pos] += x; pos += lowbit(pos); } } long long getsum_onepos(int pos) { long long sum = 0; while (pos > 0) { sum += c[pos]; pos -= lowbit(pos); } return sum; } void build() { memset(c, 0, sizeof(c)); for (int i = 1; i <= n; i++) { update_onepos(i, a[i]); } } int cmp(inst a, inst b) { return a.x < b.x; } int main(void) { int n, m; scanf("%d%d", &n, &m); int a, b; scanf("%d%d", &a, &b); for (int i = 0; i < a; i++) { scanf("%d%d", &ax[i].x, &ax[i].y); srt[i] = ax[i].y; } build(); sort(srt, srt + a); sort(ax, ax + a, cmp); for (int i = 0; i < a; i++) { cx[i] = lower_bound(srt, srt + a, ax[i].y) - srt; } long long sum = 0; for (int i = 0; i < a; i++) { update_onepos(cx[i]+1,1); sum += (i+1 - getsum_onepos(cx[i]+1)); } for (int i = 0; i < b; i++) { scanf("%d%d", &ax[i].x, &ax[i].y); srt[i] = ax[i].y; } sort(srt, srt + b); sort(ax, ax + b, cmp); build(); for (int i = 0; i < b; i++) { cx[i] = lower_bound(srt, srt + b, ax[i].y) - srt; } for (int i = 0; i < b; i++) { update_onepos(cx[i]+1, 1); sum += (i+1 - getsum_onepos(cx[i]+1)); } printf("%lld\n", sum + (long long)a*(long long)b + a + b + 1); return 0; }