题目链接

思路

四维偏序

\(CDQ\)套\(CDQ\),第一维默认有序。第二维用第一个\(CDQ\)变成有序的。并且对每个点标记上第一维属于左边还是右边。第二个\(CDQ\)处理第三维,注意两个\(CDQ\)不能用同一个数组,否则第二维就变成无序的了。最后一维用个树状数组统计答案。

代码

/*
* @Author: wxyww
* @Date: 2019-02-16 16:39:12
* @Last Modified time: 2019-02-17 08:18:59
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 50010;
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int n;
struct node {
int a,b,c,d,opt;
}a[N],tmp[N],tt[N];
bool cmp(const node &x,const node &y) {
return x.a <= y.a;
}
int tree[N];
int mx;
void update(int pos,int c) {
while(pos <= mx) {
tree[pos] += c;
pos += pos & -pos;
}
}
int query(int pos) {
int ret = 0;
while(pos) {
ret += tree[pos];
pos -= pos & -pos;
}
return ret;
}
vector<int>v;
int ans;
void cdq2(int l,int r) {
if(r <= l) return;
int mid = (l + r) >> 1;
cdq2(l,mid);
cdq2(mid + 1,r);
int L = l,R = mid + 1,now = l;
while(L <= mid && R <= r) {
if(tmp[L].c < tmp[R].c) {
if(tmp[L].opt == 1) update(tmp[L].d,1),v.push_back(tmp[L].d);
tt[now++] = tmp[L++];
}
else {
if(tmp[R].opt == 2) ans += query(tmp[R].d - 1);
tt[now++] = tmp[R++];
}
}
while(L <= mid) tt[now++] = tmp[L++];
while(R <= r) {
if(tmp[R].opt == 2) ans += query(tmp[R].d - 1);
tt[now++] = tmp[R++];
}
for(int i = l;i <= r;++i) tmp[i] = tt[i];
int k = v.size();
for(int i = 0;i < k;++i) update(v[i],-1);
v.clear();
}
void cdq(int l,int r) {
if(r <= l) return;
int mid = (l + r) >> 1;
cdq(l,mid);
cdq(mid + 1,r);
int L = l,R = mid + 1,now = l;
while(L <= mid && R <= r) {
if(a[L].b < a[R].b) tmp[now] = a[L++],tmp[now++].opt = 1;
else tmp[now] = a[R++],tmp[now++].opt = 2;
}
while(L <= mid) tmp[now] = a[L++],tmp[now++].opt = 1;
while(R <= r) tmp[now] = a[R++],tmp[now++].opt = 2;
for(int i = l;i <= r;++i) a[i] = tmp[i];
cdq2(l,r);
}
int main() {
n = read();
for(int i = 1;i <= n;++i) mx = max(mx,(a[i].a = i));
for(int i = 1;i <= n;++i) mx = max(mx,(a[i].b = read()));
for(int i = 1;i <= n;++i) mx = max(mx,(a[i].c = read()));
for(int i = 1;i <= n;++i) mx = max(mx,(a[i].d = read()));
cdq(1,n);
cout<<ans;
return 0;
}

最新文章

  1. RPC远程过程调用学习之路(一):用最原始代码还原PRC框架
  2. 前端CSS规范整理_转载、、、
  3. Linux简介及常用命令使用4--linux高级命令与技巧
  4. Oracle数据库中调用Java类开发存储过程、函数的方法
  5. 【leetcode】Fraction to Recurring Decimal
  6. 即时聊天 / XMPP
  7. NSNotificationCenter 使用姿势详解
  8. 使用MyBatis的resultMap高级查询时常用的方式总结
  9. Kemaswill 机器学习 数据挖掘 推荐系统 Ranking SVM 简介
  10. linux 中环境变量配置错误导致部分命令不能使用包括vi
  11. 分享 android 源码
  12. 并发库应用之十二 &amp; 常用集合问题汇总
  13. Groovy学习笔记-使用多赋值
  14. Azure系列2.1.8 —— BlockEntry
  15. Java Socket 死循环while如何判断客户端断开
  16. RT/Metro商店应用如何调用SQLite数据库
  17. 禁止logback输出状态信息
  18. cmake编译android平台的libPoco
  19. 事件委托,js中的一种优化方法
  20. 【Java】读写文本文件

热门文章

  1. 挖一挖MongoDB的备份与还原(实现指定时间点还原和增量备份还原)
  2. IT java培训机构名单(不全)
  3. 浅谈TCP IP协议栈(四)IP协议解析
  4. c/c++ 继承与多态 子类隐藏父类的同名非虚函数
  5. 利用ZYNQ SOC快速打开算法验证通路(2)——数据传输最简方案:网络调试助手+W5500协议栈芯片
  6. Python(五)模块
  7. 记一个bug
  8. WEB框架-Django组件学习-分页器学习
  9. Mongo字符串类型的数值查询---$Where查询介绍
  10. 模型加速[tensorflow&amp;tensorrt]