当前位置: 首页 > news >正文

QOJ1838 Intellectual Implementation 题解

\(\text{QOJ1838 Intellectual Implementation 题解}\)

其实这个题还是比较良心的,原因是保证了 \(x,y\) 互不相同,避免了一些 sb 的边界处理。

先转化一下,把每个矩形看作一个点,有交则连边,那么实际上就是求满足两两无边的三元组 \((a,b,c)\) 的个数。直接做显然没法处理,考虑容斥,设三元组有一/二/三条边的个数分别为 \(c_1,c_2,c_3\),那么 \(ans={n\choose 3}-c_1-c_2-c_3\)

全部求出来还是有点吃操作了,考虑建立一些等式代换一下。对于每两个点来考虑,会有 \((n-2)\sum d_i=2c_1+4c_2+6c_3\);从每个点来考虑,有 \(\sum{d_i\choose 2}=c_2+3c_3\),那么简单变换一发现只需要求出 \(d_i\)\(c_3\) 即可。

矩形问题我们按照 \(x\) 轴扫描线处理。对于 \(d_i\),我们开一些树状数组维护一下 \(y\) 轴的位置,那么与它有交的矩阵个数就是上边下面的下边个数减去下边下面的上边个数,这个东西画一画就能得到,但注意减去多算的自己。

对于 \(c_3\),有套路是将贡献挂在 \(x_1\) 最大的矩形上。那么对于另外矩形,若都与这个矩形的 \(x\) 轴相交由扫描线的过程可以得到这两个矩形自己 \(x\) 轴也是相交的,那么现在要求的是 \(y\) 轴同样有交的情况。

还是考虑容斥,先统计所有 \(x_1\) 小于当前矩形且有交的矩形数量,然后要减去这两个矩形之间没有交集的情形。那么实际上就是其中一个的 \(y_2\) 小于另一个的 \(y_1\),然后你会发现这个东西我们在扫描线的时候动态加删边,维护一个线段树合并信息就能做了,然后这个题就做完了。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 4e5 + 5;
int C_2(int n) {return n * (n - 1) / 2;
}
int C_3(int n) {return n * (n - 1) * (n - 2) / 6;
}
int n;
struct node {int x1, x2, y1, y2;
} e[N];
int b[N], tot;struct BIT {int lbt(int x) {return x & (-x);}int tr[N];void add(int x, int v) {while (x <= 2 * n) {tr[x] += v;x += lbt(x);}}int ask(int x) {if (x <= 0) return 0;int ans = 0;while (x) {ans += tr[x];x -= lbt(x);}return ans;}
} l1, l2, r1, r2, t1, t2;struct Node {int lct, rct, ans;
} t[N << 2];
#define lct(i) t[i].lct
#define rct(i) t[i].rct
#define ans(i) t[i].ans
#define lc (p << 1)
#define rc (lc | 1)
Node operator + (Node a, Node b) {return {a.lct + b.lct, a.rct + b.rct, a.ans + b.ans + a.lct * b.rct};
}
void updl(int p, int x, int v, int pl = 1, int pr = 2 * n) {if (pl == pr) return lct(p) += v, void();int mid = (pl + pr) >> 1;if (x <= mid) updl(lc, x, v, pl, mid);else updl(rc, x, v, mid + 1, pr);t[p] = t[lc] + t[rc];
}
void updr(int p, int x, int v, int pl = 1, int pr = 2 * n) {if (pl == pr) return rct(p) += v, void();int mid = (pl + pr) >> 1;if (x <= mid) updr(lc, x, v, pl, mid);else updr(rc, x, v, mid + 1, pr);t[p] = t[lc] + t[rc];
}
Node query(int p, int l, int r, int pl = 1, int pr = 2 * n) {if (l <= pl && pr <= r) return t[p];int mid = (pl + pr) >> 1;if (r <= mid) return query(lc, l, r, pl, mid);if (l > mid) return query(rc, l, r, mid + 1, pr);return query(lc, l, r, pl, mid) + query(rc, l, r, mid + 1, pr); 
}
int id[N], deg[N];signed main() {ios::sync_with_stdio(0);cin.tie(0);cin >> n;for (int i = 1; i <= n; i++) cin >> e[i].x1 >> e[i].x2 >> e[i].y1 >> e[i].y2;for (int i = 1; i <= n; i++) b[++tot] = e[i].x1, b[++tot] = e[i].x2;sort(b + 1, b + 1 + tot);for (int i = 1; i <= n; i++) {e[i].x1 = lower_bound(b + 1, b + 1 + tot, e[i].x1) - b;e[i].x2 = lower_bound(b + 1, b + 1 + tot, e[i].x2) - b;}tot = 0;for (int i = 1; i <= n; i++) b[++tot] = e[i].y1, b[++tot] = e[i].y2;sort(b + 1, b + 1 + tot);for (int i = 1; i <= n; i++) {e[i].y1 = lower_bound(b + 1, b + 1 + tot, e[i].y1) - b;e[i].y2 = lower_bound(b + 1, b + 1 + tot, e[i].y2) - b;}for (int i = 1; i <= n; i++) {id[e[i].x1] = i;id[e[i].x2] = -i;}int c3 = 0, sm = 0;for (int i = 1; i <= 2 * n; i++) {int x = id[i];if (x > 0) {deg[x] -= r1.ask(e[x].y2) - r2.ask(e[x].y1 - 1);c3 += C_2(t1.ask(e[x].y2) - t2.ask(e[x].y1 - 1)) - query(1, e[x].y1, e[x].y2).ans;l1.add(e[x].y1, 1);l2.add(e[x].y2, 1);t1.add(e[x].y1, 1);t2.add(e[x].y2, 1);updl(1, e[x].y2, 1);updr(1, e[x].y1, 1);}else {x *= -1;deg[x] += l1.ask(e[x].y2) - l2.ask(e[x].y1 - 1);r1.add(e[x].y1, 1);r2.add(e[x].y2, 1);t1.add(e[x].y1, -1);t2.add(e[x].y2, -1);updl(1, e[x].y2, -1);updr(1, e[x].y1, -1);			}}for (int i = 1; i <= n; i++) {--deg[i];sm += (n - 2) * deg[i];sm -= 2 * C_2(deg[i]);}sm /= 2;cout << C_3(n) - sm - c3 << '\n';return 0;
}
http://www.wxhsa.cn/company.asp?id=639

相关文章:

  • OpenSSH漏洞修复
  • 力扣15题三数之和
  • some plan
  • 利用废弃硬件中的零日漏洞:从Netgear路由器到BitDefender盒子的攻击链分析
  • ECT-OS-JiuHuaShan框架:自然规律的具象化智能体(附《易经》类比解析)
  • 力扣第5题最长回文子串
  • 用 Python 和 PaddleOCR 进行验证码识别
  • TASK 1 训练一个网络识别手写数字
  • 复杂背景验证码的识别思路与图像处理方法
  • Symfony学习笔记 - The Symfony Framework Best Practices
  • 大学军训
  • Vue Day3【综合案例2】vue小兔鲜儿
  • Java 基础知识解析
  • 力扣第3题 无重复字符的最长子串
  • UniApp 自定义导航栏
  • P3177 [HAOI2015] 树上染色
  • UniApp 自定义tabBar
  • NOIP2024复盘
  • Avalonia 学习笔记04. Page Navigation(页面导航) (转载)
  • 判断左手坐标系和右手坐标系的方法
  • 题解:P11894 「LAOI-9」Update
  • 题解:P2012 拯救世界2
  • 今日随笔
  • 一键安装小雅Alist
  • 题解:AT_abc394_c [ABC394C] Debug
  • Lumion Pro 12.0 下载安装教程包含安装包下载、安装、激活超详细图文步骤
  • 题解:CF348C Subset Sums
  • 题解:CF351B Jeff and Furik
  • 题解:CF2118D1 Red Light, Green Light (Easy version)
  • Project Euler题解思路导航(私人)