Sequence II
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description
Long long ago, there is a sequence A with length n. All numbers in this sequence is no smaller than 1 and no bigger than n, and all numbers are different in this sequence.
Please calculate how many quad (a,b,c,d) satisfy:

1≤a<b<c<d≤n
Aa<Ab
Ac<Ad
Input
The first line contains a single integer T, indicating the number of test cases.
Each test case begins with a line contains an integer n.
The next line follows n integers A1,A2,…,An.

[Technical Specification]
1 <= T <= 100
1 <= n <= 50000
1 <= Ai <= n

Output
For each case output one line contains a integer,the number of quad.

Sample Input
1
5
1 3 2 4 5

Sample Output
4

题意:有一个长度为n的数列A,数列中的每个数都在1到n之间,且数列中不存在两个相同的数。
请统计有多少四元组(a,b,c,d)满足:

1≤a<b<c<d≤n
Aa<Ab
Ac<Ad

思路:
这是道树状数组/线段树基础题。我们平时更新线段树或树状数组时都是按输入顺序从1到n更新,而还有某些题是需要你以他给定的数值大小的范围建树,把输入的数放到相对应的位置上(一般是对应位置标记),然后进行相关操作,本题即使如此。
我们讲一下树状数组的做法,线段树同理,只不过写起来麻烦一点。这道题我们按道理来说是需要每次确定四个数的,但明显会t,所以我们之多枚举一个数(这道题确定b或者确定c都可以,我们这里讲一下确定b的做法)。既然确定了b,我们就得想办法确定出b前面比它小的数和它后面满足Ac<Ad的个数,所以这里我们引入前缀和,后缀和来维护。对于刚开始而言,树状数组的所有1至n的点都是还没有被标记的,每当输入一个数时,比如输入5,我们就将它放在5的那个位置上(即更新树状数组把5的位置标记为1),这样我们去查询5前面有多少个数被标记过了,说明这些数是先被输入的,位置在这个数前面,这样子我们就维护出了一个在b前面比Ab小的数的个数的数组
那接下来我们要如何确定b后面的那些呢?这里我们可以稍微算一下,对于输入的第i个数a[i],我们已经算出了前面比它小的数pre[i],那么对于i+1位置的数来说,比它大的数就是n-a[i]-(i-1-pre[i]),n-a[i]代表i这个位置后面还有多少个数,i-1-pre[i]代表i前面有多少个数比a[i]大,这样就可以算出i后面有多少个数比a[i]大。把这个后缀和维护出来,枚举b的位置把每个点的可能种类数加起来便可,注意答案可能爆int。

代码:

  1. #include "stdio.h"
  2. #include "string.h"
  3. const int N=1e5+;
  4.  
  5. int t,n,a[N],c[N];
  6. long long ans,pre[N],last[N];
  7.  
  8. int lowbit(int x)
  9. {
  10. return x&(-x);
  11. }
  12.  
  13. int update(int x)
  14. {
  15. for(int i=x;i<=n;i+=lowbit(i))
  16. c[i]++; ///标记该点
  17. }
  18.  
  19. int getsum(int x)
  20. {
  21. int sum=;
  22. for(int i=x;i>=;i-=lowbit(i))
  23. sum+=c[i]; ///算i位置前比a[i]小的数的个数
  24. return sum;
  25. }
  26.  
  27. int main()
  28. {
  29. scanf("%d",&t);
  30. while(t--)
  31. {
  32. ans=;
  33. memset(c,,sizeof(c));
  34. memset(pre,,sizeof(pre));
  35. memset(last,,sizeof(last));
  36. scanf("%d",&n);
  37. for(int i=;i<=n;i++)
  38. {
  39. scanf("%d",&a[i]);
  40. pre[i]=getsum(a[i]); ///pre[i]代表比a[i]小的数的个数
  41. update(a[i]);
  42. }
  43. for(int i=n;i>=;i--)
  44. last[i]=n-a[i]-(i--pre[i]); ///算出i位置后面比a[i]大的数的个数
  45. for(int i=n;i>=;i--)
  46. last[i]+=last[i+]; ///累加即使i点后面满足Ac<Ad的这个数
  47. for(int i=1;i<=n;i++)
  48. ans+=(pre[i]*last[i+1]); ///枚举b点位置累加答案
  49. printf("%lld\n",ans);
  50. }
  51. return ;
  52. }

hdu 5147 Sequence II【树状数组/线段树】的更多相关文章

  1. 树状数组 && 线段树应用 -- 求逆序数

    参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...

  2. hdu1394(枚举/树状数组/线段树单点更新&区间求和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...

  3. 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树

    正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...

  4. hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...

  6. hdu 1166 敌兵布阵——(区间和)树状数组/线段树

    pid=1166">here:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Input 第一行一个整数T.表示有T组数据. 每组数据第一 ...

  7. HDU 1166 敌兵布阵 树状数组||线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=1166 题目大意: 给定n个数的区间N<=50000,还有Q个询问(Q<=40000)求区间和. 每个 ...

  8. HDU 3303 Harmony Forever 前缀和+树状数组||线段树

    Problem Description We believe that every inhabitant of this universe eventually will find a way to ...

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

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

随机推荐

  1. PHP数组——定义,类型,遍历数组,数组函数

    1.定义 $attr=array();                            //标准定义方式 $attr=[1,2]; $attr[0]="hello";     ...

  2. JuJu团队11月26号工作汇报

    JuJu团队11月26号工作汇报 JuJu   Scrum 团队成员 今日工作 剩余任务 困难 于达 对原始文本进行预处理, 并转换成可被julia读入的格式 完成预处理并用julia读入. 读入后按 ...

  3. 关于无法下载sklearn中的MNIST original数据集的问题

    在使用Sklearn进行加载自带的数据集MNIST时,总是报错,代码及相应的错误显示如下: from sklearn.datasets import fetch_mldata mnist = fetc ...

  4. 数据结构——KMP(串)

    KMP一个非常经典的字符串模式匹配算法,虽然网上有很多kmp算法的博客,但是为了更好的理解kmp我还是自己写了一遍(这个kmp的字符串存储是基于堆的(heap),和老师说的定长存储略有不同,字符串索引 ...

  5. spring mvc绑定参数之日期类型转换

    问题复现步骤: 1.提交表单,参数为: 2.接收参数类型为product实体类,如下 3.错误日志如下: org.springframework.validation.BindException: o ...

  6. Spring课程 Spring入门篇 7-3 advice扩展

    课程链接: 1 解析 1.1 advice中aspect 切面传参 1.2 通知参数名称——argNames属性, 参数为 JoinPoint.ProceedingJoinPoint.JoinPoin ...

  7. Maven与nexus关系

    一.了解Maven,Maven用来干什么呢 1. 优秀的构建工具 通过简单的命令,能够完成清理.编译.测试.打包.部署等一系列过程.同时,不得不提的是,Maven是跨平台的,无论是在Windows.还 ...

  8. 深度解析高分Essay写作组成部分

    很多留学生在国外呆了好几个学期对于怎么写Essay还是不太了解,今天小编大致总结了以下一些技巧,相信同学们可以尝试着自己完成一篇Essay写作!一起来看看吧! 与你的导师沟通 你的导师对于你的Essa ...

  9. Maven的安装和创建项目的过程

    一.下载Maven包和配置环境变量 1.将下载好的maven包放到一个目录中:目录中不能有汉字和空格 2.配置环境变量 3.配置path路径 二.配置阿里云私服 1.找到setting目录,配置下载j ...

  10. PHP笔记02

    PHP数组 能够在一个变量存储多个值 取值用下标,下标从0开始计算 好处:在处理物品清单等大量相同属性的变量内容时可以集中存取 <?php $arr=array("like" ...