题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5792

题目描述:给你n个值,每个值用A[i]表示,然后问你能否找到多少组(a,b,c,d)四个编号,四个编号互不相同,然后a < b, c < d,a代表的值小于b代表的值,c代表的值大于d代表的值。

解题思路:先考虑a和b这两个编号,遍历每一个编号作为b,然后找到b前面有多少个小于b的值,就是对于这一个编号b合理的编号a,对于每一组a和b,就可以考虑c和d,能够满足条件c和d的很显然就是除去a和b整个序列有多少个逆序对,对吧。然后对于每一个b有x个a满足条件,所以对于当前b,能够满足条件的就是(x*所有的逆序对的个数 - 逆序对中包涵a和b的个数)。所有逆序对很容易就可以用树状数组求出来,x也就是b前面有多少个小于编号b代表的值得个数,也很容易求出来,然后包涵a和b个数的逆序对呢,a前面大于A[a]的个数和a后面小于A[a]的个数,b也是一样的。

设x为对于每个b满足条件的a的个数,na代表和a有关系的逆序对,nb代表和b有关系的逆序对,tot代表所有的逆序对个数,然后对于每一个b就有 tot*x - nb*x - (所有na的值)。

代码:

#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#define inf 9223372036854775807
#define INF 9e7+5
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 5e4 + 5;
const int mod = 1e9 + 7;
const db eps = 1e-9;
ll n, c[maxn], a[maxn], num[maxn], tot, cc[maxn], lar[maxn], b[maxn]; struct pos {
ll a, ord, la;
} q[maxn]; void init() {
tot = 0;
memset(c, 0, sizeof(c));
memset(cc, 0, sizeof(cc));
memset(lar, 0, sizeof(lar)); //这个数组好像不用初始化
} ll lowbit(ll x) {
return x & (-x); //求最低位
} void updata(ll x, ll p, ll u[]) { //更新
while (x <= maxn) {
u[x] += p;
x += lowbit(x);
}
} ll getsum(ll x, ll u[]) {
ll ans = 0;
while (x > 0) {
ans += u[x];
x -= lowbit(x);
}
return ans;
}
bool cmp1(const pos&a, const pos&b)
{
return a.a<b.a;
}
bool cmp2(const pos&a, const pos&b){
return a.ord<b.ord;
} void solve() {
while (cin >> n) {
init();
for (int i = 1; i <= n; i++) {
scanf("%I64d", &q[i].a);
q[i].ord = i;
}
int pp = 0; sort(q+1, q+1+n, cmp1);
q[0].a = -1;
for (int i = 1; i <= n; i++) { //离散化
if (q[i].a != q[i-1].a) q[i].la = ++pp;
else {
q[i].la = pp;
}
}
sort(q+1, q+1+n, cmp2);
for (int i = 1; i <= n; i++) {
lar[i] = i - getsum(q[i].la, c) - 1; //求出每个数前面
updata(q[i].la, 1, c); //有多少比他大的数
}
memset(c, 0, sizeof(c));
for (int i = n; i >= 1; i--) {
num[i] = getsum(q[i].la-1, c); //求出每个数的
updata(q[i].la, 1, c); tot += num[i]; //后面比他小的个数
}
ll ans = 0; memset(c, 0, sizeof(c));
for (int i = 1; i <= n; i++) {
ll tmp = getsum(q[i].la-1, c); //对当前b满足条件的a的个数
updata(q[i].la, 1, c);
ll tt = getsum(q[i].la-1, cc); //求出和a有关系的逆序对
updata(q[i].la, num[i] + lar[i], cc);//num[i]+lar[i]就是和a有关系的逆序对
ans += tmp * tot - tt - (num[i]+lar[i])*tmp;//这里的num[i]+lar[i]是和b有关系的逆序对
}
cout << ans << endl;
}
} int main(){
//cin.sync_with_stdio(false);
//freopen("tt.txt", "r", stdin);
//freopen("isharp.out", "w", stdout);
solve(); return 0;
}

  

hdu5792 World is Exploding(多校第五场)树状数组求逆序对 离散化的更多相关文章

  1. HDU 5792:World is Exploding(树状数组求逆序对)

    http://acm.hdu.edu.cn/showproblem.php?pid=5792 World is Exploding Problem Description   Given a sequ ...

  2. HDU 6318 - Swaps and Inversions - [离散化+树状数组求逆序数][杭电2018多校赛2]

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=6318 Problem Description Long long ago, there was an ...

  3. hdu4630No Pain No Game (多校3)(树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=4630 给的题解没看懂..搜解题报告看 了N久  终于在cui大神的指点下 搞明白咋回事了 将1-N中的每个数ai ...

  4. 2015 多校联赛 ——HDU5372(树状数组)

    Sample Input 3 0 0 0 3 0 1 5 0 1 0 0 1 1 0 1 0 0   Sample Output Case #1: 0 0 0 Case #2: 0 1 0 2 有0, ...

  5. Holedox Eating HDU - 4302 2012多校C 二分查找+树状数组/线段树优化

    题意 一个长度$n<=1e5$的数轴,$m<=1e5$个操作 有两种一些操作 $0$  $x$ 在$x$放一个食物 $1$ 一个虫子去吃最近的食物,如果有两个食物一样近,不转变方向的去吃 ...

  6. HDU 4630 No Pain No Game(2013多校3 1010题 离线处理+树状数组求最值)

    No Pain No Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  7. 暴力三维树状数组求曼哈顿距离求最值——牛客多校第八场D

    涉及的知识点挺多,但是大多是套路 1.求曼哈顿距离的最值一般对所有情况进行讨论 2.三维树状数组用来求前缀最大值 /* 有一个三维坐标系(x,y,z),取值范围为[1,n],[1,m],[1,h],有 ...

  8. hdu多校第九场 1002 (hdu6681) Rikka with Cake 树状数组维护区间和/离散化

    题意: 在一块长方形蛋糕上切若干刀,每一刀都是从长方形某条边开始,垂直于这条边,但不切到对边,求把长方形切成了多少块. 题解: 块数=交点数+1 因为对于每个交点,唯一且不重复地对应着一块蛋糕. 就是 ...

  9. hdu-5792 World is Exploding(容斥+树状数组)

    题目链接: World is Exploding Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Jav ...

随机推荐

  1. Linux Shell高级技巧(目录)

    为了方便我们每个人的学习,这里将给出Linux Shell高级技巧五篇系列博客的目录以供大家在需要时参阅和查找. Linux Shell高级技巧(一) http://www.cnblogs.com/s ...

  2. Darwin Streaming Server 核心代码分析

    基本概念 首先,我针对的代码是Darwin Streaming Server 6.0.3未经任何改动的版本. Darwin Streaming Server从设计模式上看,采用了Reactor的并发服 ...

  3. http://www.cnblogs.com/Javame/p/3632473.html

    http://www.cnblogs.com/Javame/p/3632473.html

  4. vim 退出命令(保存、放弃保存)

    在命令模式中,连按两次大写字母Z,若当前编辑的文件曾被修改过,则Vi保存该文件后退出,返回到shell:若当前编辑的文件没被修改过,则Vi直接退出,   返回到shell. 在末行模式下,输入命令 : ...

  5. 038--HTML

    一.HTML的定义 1. 超文本标记语言(Hypertext Markup Language,HTML)通过标签语言来标记要显示的网页中的各个部分.一套规则,浏览器认识的规则 2. 浏览器按顺序渲染网 ...

  6. SimpleDateFormat并发隐患及其解决

    此文已由作者姚太行授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. SimpleDateFormat被大量使用于处理时间格式化过程,由于该类在创建时会指定一个pattern用于 ...

  7. tpframe免费开源框架又一重大更新

    tpframe在为Pc站.app接口.微信mobile站各种功能完善的基础上,又更新了一项重新的更新突破,以后你用tpframe开发网站,不须要在写那么多繁琐的依赖程序了,现在只须要写你关注的程序模块 ...

  8. deque双向队列

    对于双向队列,与队列queue以及vector容器的区别就在于,名字不同,也就是它是双向的,可以从头开始操作,也可以从末尾开始操作. 双向队列的常用方法跟队列queue差不多: 头文件: #inclu ...

  9. Python标准库 re

    正则表达式 regular expression 用来匹配一系列符合句法规则的字符串,是一门独立的小型的语言,如果你了解类Unix系统,那么你对正则表达式就一定不陌生.正则表达式的概念最初是由Unix ...

  10. bzoj 4542 [Hnoi2016]大数 (坑)

    题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4542 题解 Code #include<bits/stdc++.h> using ...