题意:给你三个1~n的排列a,b,c,问你在 (i,j)(1<=i<=n,1<=j<=n,i≠j),有多少个有序实数对(i,j)满足在三个排列中,i都在j的前面。

暴力求的话是三维偏序,相对比较困难。但是我们可以用一些简单的方法。

设在a中i在j前面的有序实数对数为A,b中为B,c中为C。(其实显然A=B=C=n*(n-1)/2)

要求的即为A∩B∩C。

利用容斥原理A+B+C-A∩B-A∩C-B∩C+A∩B∩C=A∪B∪C ①,以及Ω-A∪B∪C=A∩B∩C ②可容易求得。(显然Ω=n*(n-1))

②式怎么来的呢?显然,在三个序列中均满足i在j前面的有序实数对(i,j),必然与在三个序列中都未出现的有序实数对(j,i)一一对应,证毕。

而A∩B、A∩C、B∩C都可以通过二维偏序(排序+树状数组)求得。

所以最后答案就是(n*(n-1)-(n*(n-1)/2*3-A∩B-A∩C-B∩C))/2。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
int d[200005];
void Update(int p){for(;p<=n;p+=(p&(-p))) ++d[p];}
int Query(int p){int res=0; for(;p;p-=(p&(-p))) res+=d[p]; return res;}
ll A[3];
struct data{int x,y;data(const int &x,const int &y){this->x=x;this->y=y;}data(){}
}a[200005],b[200005],c[200005],p[3][200005];
bool operator < (const data &a,const data &b){return a.x<b.x;
}
int main(){
//  freopen("g.in","r",stdin);scanf("%d",&n);for(int i=1;i<=n;++i){scanf("%d",&a[i].x);a[i].y=i;}sort(a+1,a+n+1);for(int i=1;i<=n;++i){scanf("%d",&b[i].x);b[i].y=i;}sort(b+1,b+n+1);for(int i=1;i<=n;++i){scanf("%d",&c[i].x);c[i].y=i;}sort(c+1,c+n+1);for(int i=1;i<=n;++i){p[0][i]=data(a[i].y,b[i].y);p[1][i]=data(a[i].y,c[i].y);p[2][i]=data(b[i].y,c[i].y);}for(int i=0;i<3;++i){sort(p[i]+1,p[i]+n+1);memset(d,0,sizeof(d));for(int j=1;j<=n;++j){A[i]+=(ll)Query(p[i][j].y);Update(p[i][j].y);}}printf("%I64d\n",((ll)n*(ll)(n-1)-((ll)n*(ll)(n-1)/2ll*3ll-A[0]-A[1]-A[2]))/2ll);return 0;
}

转载于:https://www.cnblogs.com/autsky-jadek/p/7700491.html

【容斥原理】【推导】【树状数组】Gym - 101485G - Guessing Camels相关推荐

  1. Gym - 101744E卡了我半天的题。。。。原来是才学的树状数组。。。

    最近学的不错的树状数组...比赛的时候居然忘记了,害的我卡了半天,心态炸掉了...再写一下题解 http://codeforces.com/gym/101744/problem/E 其实本题就是一个给 ...

  2. Codeforces Gym 100114 H. Milestones 离线树状数组

    H. Milestones Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100114 Descripti ...

  3. Gym - 101755G Underpalindromity (树状数组)

    Let us call underpalindromity of array b of length k the minimal number of times one need to increme ...

  4. Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)

    题意: 树的根节点为水源,编号为 1 .给定编号为 2, 3, 4, -, n 的点的父节点.已知只有叶子节点都是房子. 有 q 个操作,每个操作可以是下列两者之一: + v ,表示编号为 v 的房子 ...

  5. Gym - 101889F Fundraising(树状数组求带权最长上升子序列)

    ICPC Latin American Regional – 2017 Problem F – Fundraising Author: Paulo Cezar Pereira Costa, Brasi ...

  6. 树状数组求区间和模板 区间可修改 参考题目:牛客小白月赛 I 区间

    从前有个东西叫树状数组,它可以轻易实现一些简单的序列操作,比如单点修改,区间求和;区间修改,单点求值等. 但是我们经常需要更高级的操作,比如区间修改区间查询.这时候树状数组就不起作用了,只能选择写一个 ...

  7. P4062 [Code+#1]Yazid 的新生舞会 树状数组维护三阶差分

    传送门 文章目录 题意: 思路: 题意: 给你一个序列aaa,让你求有多少个子区间满足存在一个数是这个区间的绝对众数,绝对众数指该数在区间内出现的次数严格大于r−l+12\frac{r-l+1}{2} ...

  8. [省选联考 2020 A/B 卷] 冰火战士(树状数组上二分)

    文章目录 problem solution(10pts) code(10pts) solution(30pts) code(30pts) solution(60pts) code(60pts) sol ...

  9. HDU5126 stars(4维偏序->cdq套cdq+树状数组)

    stars 题目大意: 在一个三维空间当中,每次进行一个操作,添加一个点或者统计空间中的某一个长方体范围内的所有点 三维空间中我们用两个点即可确定一个长方体. 首先效仿平面二维数点的方法,根据容斥原理 ...

最新文章

  1. 如何构建优质的推荐系统服务?| 技术头条
  2. 通过类名和窗口名查找指定窗口
  3. 15、iOS开发之duplicate symbols for architecture x86_64错误
  4. python之路-SQLAlchemy
  5. c语言上机实验作业答案,第十二次C语言上机实验参考答案
  6. 使用 Jenkins + GitHub + Nginx + HTTPS 搭建静态网站
  7. 强化学习(RL)AlphaGo Zero训练五子棋
  8. Spring IOC源码分析
  9. 小程序中的flex_在Flex应用程序中启用辅助功能
  10. matlab的句柄 图形对象 gca gco gcf set get
  11. Gerrit 工作流程及简单使用
  12. 跑马灯实现的三种方式
  13. 两点分布和二项分布的特征函数
  14. openfoam学习心得——openfoam编程进阶
  15. 测试hadoop服务器NodeManager无法连接ResourceManager问题
  16. Mongoose使用操作
  17. Unity 物理系统 -- 碰撞体简介(碰撞、触发条件)
  18. Java第十六天~第十七天/11.18~11.19
  19. 阿里P8共勉之-送书帖-听说最近你读过不少书?
  20. linux scp将服务器上的文件下载到本地

热门文章

  1. 新手如何快速入门node.js
  2. 下载安装MarkDown保姆级
  3. 用一条SQL 语句 查询出每门课都大于80 分的学生姓名
  4. 我的linux学习笔记
  5. mysql 两表关联 分组查询
  6. CANoe——CAPL(Message)
  7. Android数据恢复工具
  8. rstudio中logit模型代码
  9. Arduino智能小车设计(七)
  10. 女程序员放弃大厂年薪20万,回老家当实习老师,工作难找,后悔哭了