题目大意:

Given a sequence A with length n,count how many quadruple (a,b,c,d) satisfies: a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ada≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad.

A1,A2⋯AnA1,A2⋯An.  1≤n≤500001≤n≤50000  0≤Ai≤1e9

基本思路:

最朴素的思想就是算出所有顺序对所有逆序对相乘然后再减去所有有重复元素的结果,最终得到答案;

将原数组排序后去重然后从1开始标号(离散化),然后线段树维护某个标号有多少个数;

min_[i]:表示原数组下标在1~i-1的数比下标为i的数小的数的个数;

max_[i]:表示原数组下标在1~i-1的数比下标为i的数大的数的个数;

hmin_[i]:表示原数组下标在i之后的数比下标为i的数小的数的个数;

hmax_[i]:表示原数组下标在i之后的数比下标为i的数大的数的个数;

num[i]:树状数组的维护数组;

sum[i]:表示到下标为i的数中,从中任意挑出两个数满足下标小的数小于下标大的数的个数;

接下来枚举当前ai作为Vd,那么就存在mx[i]个Vc,以及sum[n]对Va,Vb。res+=mx[i]*sum[n]

由于答案会多算进去a=c || a=d || b=c || b=d的情况,那么枚举这四种情况减去就可以了,a=c那么必定b!=d,同理其他

a=c:ans-=hmn[i]*hmx[i]

a=d:ans-=mx[i]*hmx[i]

b=c:ans-=mn[i]*hmn[i]

b=d:ans-=mx[i]*mn[i]

反思与总结:

//对于树状数组,我一直有所顾忌,因为就比如num【4】的值并不加和在num【6】里,其实没必要了,因为树状数组用到的操作就是求和和求最大最小值,然后求和的话并不是直接用这些数组元素,而是一个模板函数去求,这个函数求出来的就是1~i的加和,然后求某一个区间的话就是相减,没有任何问题,而且对于树状数组维护的东西又有了较为深刻的认识(可以把其他的值一转化来维护);

//以后的话可以将某些对象抽象,从抽象层面考虑问题,也许问题会变得更容易想,这就是教主说的改变思维方式吧,走出思维的舒适区;

//我还发现对于一个对象在一个程序中,可以分别赋予多种抽象,前提是一个用完之后再用另一个不能混着来;

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; typedef long long ll; const int maxn = +;
int max_[maxn],min_[maxn],hmin_[maxn],hmax_[maxn];
int num[maxn],a[maxn],b[maxn],sum[maxn];
ll res;
int n,m; int lowbit(int x)
{
return x&(-x);
} void add(int x)
{
while(x<=m)
{
num[x]++;
x+=lowbit(x);
}
} int query(int x)
{
int ans=;
while(x>=)
{
ans+=num[x];
x-=lowbit(x);
}
return ans;
} int main()
{
while(scanf("%d",&n)==)
{
for(int i=;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
sort(b+,b+n+);
m=unique(b+,b+n+)-(b+);
for(int i=;i<=n;i++) a[i]=lower_bound(b+,b+m+,a[i])-b;
memset(num,,sizeof(num));
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++)
{
min_[i]=query(a[i]-);
max_[i]=query(m)-query(a[i]);
sum[i]=sum[i-]+min_[i];
add(a[i]);
}
memset(num,,sizeof(num));
for(int i=n;i>=;i--)
{
hmin_[i]=query(a[i]-);
hmax_[i]=query(m)-query(a[i]);
add(a[i]);
}
res=;
ll num1,num2;
for(int i=;i<=n;i++)
{
num1=max_[i];
num2=sum[n];
res+=num1*num2;
}
//a=c&&b!=d;
for(int i=;i<=n;i++)
{
num1=hmin_[i];
num2=hmax_[i];
res-=num1*num2;
}
//a!=c&&b=d;
for(int i=;i<=n;i++)
{
num1=min_[i];
num2=max_[i];
res-=num1*num2;
}
//a=d&&b!=c;
for(int i=;i<=n;i++)
{
num1=max_[i];
num2=hmax_[i];
res-=num1*num2;
}
//a!=d&&b=c;
for(int i=;i<=n;i++)
{
num1=hmin_[i];
num2=min_[i];
res-=num1*num2;
}
printf("%I64d\n",res);
}
return ;
}

hdu 5792 树状数组+离散化+思维的更多相关文章

  1. hdu 5792(树状数组,容斥) World is Exploding

    hdu 5792 要找的无非就是一个上升的仅有两个的序列和一个下降的仅有两个的序列,按照容斥的思想,肯定就是所有的上升的乘以所有的下降的,然后再减去重复的情况. 先用树状数组求出lx[i](在第 i ...

  2. HDU 1394 树状数组+离散化求逆序数

    对于求逆序数问题,学会去利用树状数组进行转换求解方式,是很必要的. 一般来说我们求解逆序数,是在给定一串序列里,用循环的方式找到每一个数之前有多少个比它大的数,算法的时间复杂度为o(n2). 那么我们 ...

  3. [hdu 4417]树状数组+离散化+离线处理

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 把数字离散化,一个查询拆成两个查询,每次查询一个前缀的和.主要问题是这个数组是静态的,如果带修改 ...

  4. Disharmony Trees HDU - 3015 树状数组+离散化

    #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using ...

  5. hdu 4325 树状数组+离散化

    思路:这题的思路很容易想到,把所有时间点离散化,然后按时间一步一步来,当到达时间i的时候处理所有在i处的查询. 这个代码怎一个挫字了得 #include<iostream> #includ ...

  6. Swaps and Inversions HDU - 6318 树状数组+离散化

    #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> us ...

  7. C - The Battle of Chibi HDU - 5542 (树状数组+离散化)

    Cao Cao made up a big army and was going to invade the whole South China. Yu Zhou was worried about ...

  8. hdu 4638 树状数组 区间内连续区间的个数(尽可能长)

    Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  9. hdu 4777 树状数组+合数分解

    Rabbit Kingdom Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

随机推荐

  1. 力扣——Copy List with Random Pointer(复制带随机指针的链表) python实现

    题目描述: 中文: 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点. 要求返回这个链表的深拷贝. 示例: 输入:{"$id":" ...

  2. python2和python3中TestSuite().addTest的区别

    Python2中unittest.TestSuite().addTest()的参数是这样的:unittest.TestSuite().addTest(TestFun("test_nam&qu ...

  3. 设置php的环境变量 php: command not found

    执行远程服务器上的某个脚本,却报错,提示php:command not found 找不到php命令 which php  结果是/usr/local/php/bin/php echo $PATH 结 ...

  4. [BOOKS]Big Data: Principles and best practices of scalable realtime data systems

  5. 【leetcode】926.Flip String to Monotone Increasing

    题目如下: A string of '0's and '1's is monotone increasing if it consists of some number of '0's (possib ...

  6. php strrev()函数 语法

    php strrev()函数 语法 strrev()怎么用? php strrev()函数用于反转字符串,语法是strrev(string),返回已反转的字符串.大理石构件来图加工 作用:反转字符串 ...

  7. 探索Redis设计与实现9:数据库redisDb与键过期删除策略

    本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...

  8. docker-compose快速搭建 Prometheus+Grafana监控系统

    一.说明Prometheus负责收集数据,Grafana负责展示数据.其中采用Prometheus 中的 Exporter含:1)Node Exporter,负责收集 host 硬件和操作系统数据.它 ...

  9. share memory cache across multi web application

    Single instance of a MemoryCache across multiple application pools on the same server [duplicate] Yo ...

  10. 爬取猎聘大数据岗位相关信息--Python

    猎聘网站搜索大数据关键字,只能显示100页,爬取这一百页的相关信息,以便做分析. __author__ = 'Fred Zhao' import requests from bs4 import Be ...