三元环

HDU - 7439

思路

考虑 \(3\) 个点的有向图,要么成环,要么有一个点入度为 \(2\) ,假设第 个点的入度为 \(d_i\),答案为 \(C_n^3-\sum\limits_{i=1}^nC_{d_i}^2\)。

根据题目关系,\(i\rightarrow j\) 当且仅当 \(i<j \ and\ f_i <f_j \ and\ g_i < g_j\),否则就是 \(j\rightarrow i\),所以根据这个三维关系,我们可以先根据前两维求出 \(i<j\ and\ f_i\ge f_j\) 的入度,然后通过 cdq分治去求满足这个三维关系的各点的度数。

代码

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

template<typename T>
struct BIT {
#ifndef lowbit
#define lowbit(x) (x & (-x));
#endif
int n;
vector<T> t; BIT () {}
BIT (int _n): n(_n) { t.resize(_n + 1); }
BIT (int _n, vector<T>& a): n(_n) {
t.resize(_n + 1);
for (int i = 1; i <= n; ++ i) {
t[i] += a[i];
int j = i + lowbit(i);
if (j <= n) t[j] += t[i];
}
}
//单点修改
void update(int i, T x) {
while (i <= n) {
t[i] += x;
i += lowbit(i);
}
}
//区间查询
T sum(int i) {
T ans = 0;
while (i > 0) {
ans += t[i];
i -= lowbit(i);
}
return ans;
} T query(int i, int j) {
return sum(j) - sum(i - 1);
}
//区间修改则存入差分数组,[l, r] + k则update(x,k),update(y+1,-k)
//单点查询则直接求前缀和sum(x) //求逆序对
/*
iota(d.begin(), d.end(), 0);
stable_sort(d.begin(), d.end(), [&](int x, int y) {
return a[x] < a[y];
});去重排序 BIT<i64> tree(n);
i64 ans = 0;
for (int i = 1; i <= n; i ++) {
tree.update(d[i], 1);
ans += i - tree.sum(d[i]);
}
*/
}; int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); int n;
cin >> n; vector<array<int, 3>> a(n + 1);
for (int i = 1; i <= n; i ++) {
cin >> a[i][0];
a[i][2] = i;
} for (int i = 1; i <= n; i ++) {
cin >> a[i][1];
} BIT<i64> bit(n);
vector<int> in(n + 1);
//求 i < j and fi >= fj
for (int i = n; i >= 1; i --) {
in[i] += bit.sum(a[i][0]);
bit.update(a[i][0], 1);
} for (int i = n; i >= 1; i --) {
bit.update(a[i][0], -1);
} auto cdq = [&](auto && self, int l, int r)->void{
if (l == r)
return ; int mid = l + r >> 1;
self(self, l, mid);
self(self, mid + 1, r); sort(a.begin() + l, a.begin() + mid + 1, [](auto x, auto y) {
if (x[0] != y[0]) return x[0] < y[0];
return x[1] < y[1];
}); sort(a.begin() + mid + 1, a.begin() + r + 1, [](auto x, auto y) {
if (x[0] != y[0]) return x[0] < y[0];
return x[1] < y[1];
}); //求 i < j and fi < fj and gi < gj
int i = l, j = mid + 1;
while (j <= r) {
while (i <= mid && a[i][0] < a[j][0]) {
bit.update(a[i][1], 1);
i ++;
}
in[a[j][2]] += bit.sum(a[j][1] - 1);
j ++;
}
for (int k = l; k < i; k ++) {
bit.update(a[k][1], -1);
} //求 i < j and fi < fj and gi >= gj
i = mid, j = r;
while (i >= l) {
while (j > mid && a[j][0] > a[i][0]) {
bit.update(a[j][1], 1);
j --;
}
in[a[i][2]] += bit.sum(a[i][1]);
i --;
}
for (int k = r; k > j; k --) {
bit.update(a[k][1], -1);
}
}; cdq(cdq, 1, n); i64 ans = 1ll * n * (n - 1) * (n - 2) / 6;
for (int i = 1; i <= n; i ++) {
ans -= 1ll * in[i] * (in[i] - 1) / 2;
} cout << ans << '\n'; return 0;
}

【CDQ分治】三元环的更多相关文章

  1. Codeforces 434E - Furukawa Nagisa's Tree(三元环+点分治)

    Codeforces 题面传送门 & 洛谷题面传送门 场号 hopping,刚好是我的学号(指 round 的编号) 注:下文中分别用 \(X,Y,K\) 代替题目中的 \(x,y,k\) 注 ...

  2. 【BZOJ3456】【CDQ分治+FNT】城市规划

    试题来源 2013中国国家集训队第二次作业 问题描述 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得 ...

  3. Codeforces 938G(cdq分治+可撤销并查集+线性基)

    题意: 有一个无向连通图,支持三个操作: 1 x y d : 新建一条x和y的无向边,长度为d 2 x y    :删除x和y之间的无向边 3 x y    :询问x到y的所有路径中(可以绕环)最短的 ...

  4. 技巧专题3(cdq分治、整体二分等)

    cdq分治与整体二分 cdq来源于2008年国家集训队作业陈丹琦(雅礼巨佬),用一个log的代价完成从静态到动态(很多时候是减少时间那一维的). 对于一个时间段[L, R],我们取mid = (L + ...

  5. 【教程】简易CDQ分治教程&学习笔记

    前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦!       CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...

  6. BZOJ 2683 简单题 ——CDQ分治

    [题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...

  7. HDU5618 & CDQ分治

    Description: 三维数点 Solution: 第一道cdq分治...感觉还是很显然的虽然题目不能再傻逼了... Code: /*=============================== ...

  8. 初识CDQ分治

    [BZOJ 1176:单点修改,查询子矩阵和]: 1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 200 ...

  9. HDU5322 Hope(DP + CDQ分治 + NTT)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5322 Description Hope is a good thing, which can ...

  10. BZOJ4170 极光(CDQ分治 或 树套树)

    传送门 BZOJ上的题目没有题面-- [样例输入] 3 5 2 4 3 Query 2 2 Modify 1 3 Query 2 2 Modify 1 2 Query 1 1 [样例输出] 2 3 3 ...

随机推荐

  1. BST-Treap名次树数组&指针实现板子 Ver1.0

    这里只有板子没有原理QWQ 可实现 1.插入 x 数 2.删除 x 数(若有多个相同的数,只删除一个) 3.查询 x 数的排名(排名定义为比当前数小的数的个数 +1) 4.查询排名为 x 的数 5.求 ...

  2. C# 时间戳与 标准时间互转

    C# 时间戳与 标准时间的转其实不难,但需要注意下,基准时间的问题. 格林威治时间起点: 1970 年 1 月 1 日的 00:00:00.000 北京时间起点:1970 年 1 月 1 日的 08: ...

  3. gdb 根据c语言二进制文件进程号查看内部多线程任务

    C语言二进制文件 a 编译时添加了 -g (gdb 调试), 但是 gdb a 这种方式有时不容易复现一些场景.这时可以先正常启动 a, 然后根据 a 的进程号启动gdb调试. # 1. 找到程序进程 ...

  4. mac svn管理工具

    App Store中搜索snailsvn 分付费(98元)和免费试用

  5. Vue bug from backend

    一个后端引发前端的BUG 使用的框架是vue 代码里面有一个组件 <table :data="data"/> 获取后台数据 this.data = await fetc ...

  6. 火山引擎ByteHouse发布高性能全文检索引擎

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群.  随着数字时代的发展,数据的来源和生成方式越来越广泛,数据形态也愈加丰富.   以某电商平台的数据情况举例.该电 ...

  7. 基于Java+Spring+Vue仓储出入库管理系统设计和实现

    \n文末获取源码联系 感兴趣的可以先收藏起来,大家在毕设选题,项目以及论文编写等相关问题都可以给我加好友咨询 系统介绍: 网络的广泛应用给生活带来了十分的便利.所以把仓储出入库管理与现在网络相结合,利 ...

  8. 一文揭开JDK21虚拟线程的神秘面纱

    虚拟线程快速体验 环境:JDK21 + IDEA public static void main(String[] args) { try (var executor = Executors.newV ...

  9. 使用win server 2019服务器的iis服务发布静态网页

    1.首先远程连接到服务器 2.打开服务器管理器 3添加角色和功能 4.安装类型:选择基于角色或基于功能的安装  →服务器角色:从服务器池中选择服务器 5.服务器角色选择Web服务器(iis) 6.功能 ...

  10. JavaWeb编写登录注册案例并把数据插入MySQL数据库中

    小白学习了这么久的java,第一次上手编写一个完整的登录以及注册案例,麻雀虽小五脏俱全!!!! 案例: 登录和注册 第一:所需创建的包以及相关类 1,domain包(也就是平时所说的Javabean) ...