HDOJ 5147 Sequence II 树阵

树阵:

每个号码的前面维修比其数数少,和大量的这后一种数比他的数字

再枚举每一个位置组合一下

Sequence II

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

Total Submission(s): 121    Accepted Submission(s): 58

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. 1≤a<b<c<d≤n

2. Aa<Ab

3. 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

Source

BestCoder Round #23

/* ***********************************************
Author        :CKboss
Created Time  :2014年12月20日 星期六 21时38分00秒
File Name     :HDOJ5147.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

typedef long long int LL;

const int maxn=55000;

int a[maxn];
int n;

LL sum1[maxn],sum2[maxn];
int t1[maxn],t2[maxn];

int lowbit(int x) { return x&(-x); }

/// 1 找比当前数小的 2 找比当前数大的

void init()
{
	memset(sum1,0,sizeof(sum1));
	memset(sum2,0,sizeof(sum2));
	memset(t1,0,sizeof(t1));
	memset(t2,0,sizeof(t2));
}

void add(int kind,int p)
{
	if(kind==1) for(int i=p;i<maxn;i+=lowbit(i)) t1[i]+=1;
	else if(kind==2) for(int i=p;i;i-=lowbit(i)) t2[i]+=1;
}

int sum(int kind,int p)
{
	int ret=0;
	if(kind==1) for(int i=p;i;i-=lowbit(i)) ret+=t1[i];
	else if(kind==2) for(int i=p;i<maxn;i+=lowbit(i)) ret+=t2[i];
	return ret;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);

	int T_T;
	scanf("%d",&T_T);
	while(T_T--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%d",a+i);

		init();

		/// from left to right
		for(int i=1;i<=n;i++)
		{
			int ss=sum(1,a[i]);
			sum1[i]=ss;
			add(1,a[i]);
		}
		/// from right to left
		for(int i=n;i>=1;i--)
		{
			int ss=sum(2,a[i]);
			sum2[i]=sum2[i+1]+ss;
			add(2,a[i]);
		}

		LL ans=0;
		for(int i=2;i<=n-1;i++)
		{
			/// X...i i+1...X
			ans+=sum1[i]*sum2[i+1];
		}

		cout<<ans<<endl;
	}

    return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-10-01 23:43:40

HDOJ 5147 Sequence II 树阵的相关文章

HDOJ 5147 Sequence II 树状数组

树状数组: 维护每一个数前面比它小的数的个数,和这个数后面比他大的数的个数 再枚举每个位置组合一下 Sequence II Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 121    Accepted Submission(s): 58 Problem Description Long long ago, there is a seq

hdu 5147 Sequence II(树状数组)

题目链接:hdu 5147 Sequence II 预处理每个位置作为b和c可以组成的对数,然后枚举b的位置计算. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 50005; int N, arr[maxn], fenw[maxn], lef[maxn], rig[maxn]; #d

hdu 5147 Sequence II (树状数组 求逆序数)

题目链接 Sequence II Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 331    Accepted Submission(s): 151 Problem Description Long long ago, there is a sequence A with length n. All numbers in this se

HDU 5147 Sequence II 树状数组水题

无聊咯,学某y,水一发 给你n个数的排列,A[1]到A[n],统计多少四元组(a,b,c,d)满足,1<=a<b<c<d<=n,且A[a]<A[b],A[c]<A[d] 树状数组统计前缀和咯 1 #include<cstdio> 2 #include<cstring> 3 #include<cctype> 4 typedef long long ll; 5 const int maxn=5e4+10; 6 int T,n,a[m

[ACM] hdu 5147 Sequence II (树状数组,前缀和,后缀和)

Sequence II 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) satis

bestcoder#23 1002 Sequence II 树状数组+DP

Sequence II Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 652    Accepted Submission(s): 164 Problem Description Long long ago, there is a sequence A with length n. All numbers in this sequenc

Hdu 5147 Sequence II(树状数字 or 线段树 + 输入外挂 前缀和+后缀和)

题意: 给定1~n的一个排列 用A[]数组保存,问有多少下标(a,b,c,d)四元组满足: a 解析: 题目中n的范围是50000,O(n^2) 复杂度肯定超时.那么这题明显考察的是log2(n)的算法,对于这题可以用线段树或者树状数组,同时要用到输入外挂,不然会超时. 思路(参考别人做法) 枚举c的位置,那么每一次枚举中的方法数为 1~c-1 中(a,b)的个数 乘以 c~n中(c,d)的个数.累加起来即为答案. 1~c-1中(a,b)的个数相当于枚举b的位置,然后计算出b前面有多少数比A[b

hdu 5147 Sequence II

http://acm.hdu.edu.cn/showproblem.php?pid=5147 题意:问有多少个这样的四元组(a,b,c,d),满足条件是 1<=a<b<c<d; Aa<Ab; Ac<Ad; 思路:用树状数组求,从右向左求在这个数之前形成多少个逆序数对记录在r数组里面,然后在从左向右求出在输入这个数之前形成多少个逆序数对存在l数组里面,然后枚举b就行: 1 #include <cstdio> 2 #include <cstring>

UVA 10869 - Brownie Points II(树阵)

UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线.然后还有一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分出4个象限,第一个人得到分数为1.3象限,第二个人为二四象限.问第一个个人按最优取法,能得到最小分数的最大值,和这个值下还有一个人的得分可能情况 思路:树状数组,能够枚举一点,假设能求出右上和左下点的个数就好办了,其有用一个树状数组,把y坐标离散化掉,然后记录进来,然后把点按x从左往右,每次删掉点后