HDU-5792
来源:互联网 发布:淘宝网pc客户端下载 编辑:程序博客网 时间:2024/06/06 02:50
点击打开题目链接
World is Exploding
Problem DescriptionGiven 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>Ad .
InputThe input consists of multiple test cases.
Each test case begin with an integer n in a single line.
The next line contains n integers A1,A2⋯An .
1≤n≤50000
0≤Ai≤1e9
OutputFor each test case,output a line contains an integer.
Sample Input42 4 1 341 2 3 4
Sample Output10
Each test case begin with an integer n in a single line.
The next line contains n integers
42 4 1 341 2 3 4
10
题意很明确,就是让我们求一个四元组,满足 a<b并且c<d.
解题思路:可以求出所有的四元组数目减去不符合条件四元组的数目,就可以得到我们需要的了。具体怎么实现呢,做这个题顺便学习了一下树状数组(百度百科有很详细的解释),真是很神奇的东西。但是这道题确实让我转了很大的圈子。具体解释详见代码。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cstring>using namespace std;long long a[50001],b[50001],c[50001],aa[50001];long long yx[50001],yd[50001],zx[50001],zd[50001];long long n;long long num; // 这里全部用 long long 是为了省事儿 long long get_k(long long k){return k&-k;}void add(long long pos,long long val){while(pos<=n){c[pos] += val; // 数组c是用来存储树状数组的值 pos += get_k(pos);}return ;}long long get_sum(long long pos){long long ans = 0;while(pos>0){ ans += c[pos]; pos -= get_k(pos);} return ans;} // 以上三个函数为对树状数组的操作 ,百度百科可以很详细的学习树状数组。 int main(){ while(scanf("%lld",&n)!=EOF) {memset(c,0,sizeof(c));memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(yx,0,sizeof(yx));memset(yd,0,sizeof(yd));memset(zx,0,sizeof(zx));memset(zd,0,sizeof(zd)); for(int i=1;i<=n;i++){scanf("%lld", &a[i]);b[i] = a[i];}sort(b+1,b+1+n); num = unique(b+1,b+1+n) - (b+1); //排序去重,方便离散化,其实这一步有没有都能AC。 long long sum1,sum2; sum1 = sum2 = 0; //两个for循环,正反各一次 for(int i=1;i<=n;i++) {long long pos = lower_bound(b+1,b+1+num,a[i]) - b; // 每次找到a[i]的位置,如果没用unique,num就改为n add(pos,1);zx[i] = get_sum(pos-1); //左边比a[i]小的数目 zd[i] = i - get_sum(pos);//左边比a[i]大的数目 } memset(c,0,sizeof(c)); // 反向循环的时候树状数组要清空重建 for(int i=n; i>=1; i--) { long long pos = lower_bound(b+1,b+1+n,a[i]) - b; add(pos,1); yx[i] = get_sum(pos-1); // 右边比a[i]小的数目 yd[i] = n-i+1 - get_sum(pos); //右边比a[i]大的数目 sum1 += yx[i];sum2 += yd[i];} long long pp = sum1 * sum2; // 所有的四元组 /*重复的情况有四种 即 ac重复,ad重复,bc重复,bd重复 */ for(int i=1;i<=n;i++) { pp -= zx[i]*yx[i]; pp -= zd[i]*yd[i]; pp -= zx[i]*zd[i]; pp -= yx[i]*yd[i]; } printf ("%lld\n",pp); }return 0;}
水波
0 0
- HDU-5792
- HDU 5792 树状数组
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)
- Prometheus 实战于源码分析之部署
- Error:(896) Apostrophe not preceded by \
- httpURLConnection post请求 然后使用Gson转换成想要的class
- Java并发编程:并发容器之CopyOnWriteArrayList(转载)
- HDU-5792
- 台湾大学林轩田机器学习基石课程学习笔记2 -- Learning to Answer Yes/No
- springmvc接收数组的方式
- MTK 修改ro.hardware 获取cpu 和固件版本号方法
- hdu4607双dfs求树的直径+公式
- Android的消息呼吸灯闪烁
- 基于jackson注释@JsonFormat 格式化时间少8小时
- WindowManger 事件接收 不能接收onTouch
- spring 自带的定时任务