hdu 5792 World is Exploding(2016 Multi-University Training Contest 5——树状数组)
2016-08-03 20:11
477 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5792
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 643 Accepted Submission(s): 306
Problem Description
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>Ad.
Input
The 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
Output
For each test case,output a line contains an integer.
Sample Input
4
2 4 1 3
4
1 2 3 4
Sample Output
1
0
Author
ZSTU
Source
2016 Multi-University Training Contest 5
题目大意:
给n个数,问有多少个四元组,满足a≠b≠c≠d1≤a<b≤n,1≤c<d≤n,
Aa<Ab,Ac>Ad1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad打住
这里a,b,c,d两两不相等。
解题思路:
先找出逆序对和升序对,把两个得到的数乘起来在减去不合法的即可。
其中不合法的就是长度为3的,有一些重复计算了的减掉。
四个数组,lmax表示他左边有多少个比他大的,lmin表示左边有多少小的
rmax,rmin分别表示右边有多少大的和小的。
这里由于0≤Ai≤1e9,所以在传参不可能这么大,所以我们要预先的a[i]这个数组进行离散化处理。
离散化的处理方法就是:找到相应的序列,对他排序,在给每一个重新复制,从1开始,这样最多也就50000,。
这里做的原因是我们这个题目和数值没有关系,至于前后左右的大小有关。
详见代码。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
#define N 50010
#define ll long long
int a
,c
;
int lmax
,lmin
,rmax
,rmin
;
vector<int>V;
map<int,int>M;
int lowbit(int k)
{
return k&((k)xor(k-1));
}
void add(int num,int k)
{
while (k<N)
{
c[k]+=num;
k+=lowbit(k);
}
}
int sum(int k)
{
int s=0;
while (k)
{
s+=c[k];
k-=lowbit(k);
}
return s;
}
int main()
{
int n;
ll s1,s2,s,cnt,ans;
while (~scanf("%d",&n))
{
s1=s2=cnt=0;
V.clear();
M.clear();
for (int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
V.push_back(a[i]);
}
sort(V.begin(),V.end());
V.erase(unique(V.begin(),V.end()),V.end());//去重,把整个区间内重复的数都当成一个数
for (int i=0;i<V.size();i++)
{
M[V[i]]=i+1;//给每个数重新编号
}
for (int i=1;i<=n;i++)
a[i]=M[a[i]];
memset(c,0,sizeof(c));
for (int i=1; i<=n; i++)
{
add(1,a[i]);
lmin[i]=sum(a[i]-1);//当前位置左边比他小的有多少个
lmax[i]=sum(N-1)-sum(a[i]);//已经出现的数肯定是他左边的数,在这个时候记录数轴上有多少个数再减去小于等于的,就是大于的了
}
memset(c,0,sizeof(c));
for (int i=n; i>=1; i--)
{
add(1,a[i]);
rmin[i]=sum(a[i]-1);
rmax[i]=sum(N-1)-sum(a[i]);
}
for (int i=1; i<=n; i++)
{
s1+=lmin[i];//升序的对数
s2+=lmax[i];//逆序的对数
}
s=s1*s2;
// cout<<s<<endl;
for (int i=1;i<=n;i++)
{
cnt+=lmax[i]*lmin[i]+rmax[i]*rmin[i]+lmax[i]*rmax[i]+lmin[i]*rmin[i];
}
//cout<<cnt<<endl;
ans=s-cnt;
printf ("%lld\n",ans);
}
return 0;
}
World is Exploding
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 643 Accepted Submission(s): 306
Problem Description
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>Ad.
Input
The 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
Output
For each test case,output a line contains an integer.
Sample Input
4
2 4 1 3
4
1 2 3 4
Sample Output
1
0
Author
ZSTU
Source
2016 Multi-University Training Contest 5
题目大意:
给n个数,问有多少个四元组,满足a≠b≠c≠d1≤a<b≤n,1≤c<d≤n,
Aa<Ab,Ac>Ad1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad打住
这里a,b,c,d两两不相等。
解题思路:
先找出逆序对和升序对,把两个得到的数乘起来在减去不合法的即可。
其中不合法的就是长度为3的,有一些重复计算了的减掉。
四个数组,lmax表示他左边有多少个比他大的,lmin表示左边有多少小的
rmax,rmin分别表示右边有多少大的和小的。
这里由于0≤Ai≤1e9,所以在传参不可能这么大,所以我们要预先的a[i]这个数组进行离散化处理。
离散化的处理方法就是:找到相应的序列,对他排序,在给每一个重新复制,从1开始,这样最多也就50000,。
这里做的原因是我们这个题目和数值没有关系,至于前后左右的大小有关。
详见代码。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
#define N 50010
#define ll long long
int a
,c
;
int lmax
,lmin
,rmax
,rmin
;
vector<int>V;
map<int,int>M;
int lowbit(int k)
{
return k&((k)xor(k-1));
}
void add(int num,int k)
{
while (k<N)
{
c[k]+=num;
k+=lowbit(k);
}
}
int sum(int k)
{
int s=0;
while (k)
{
s+=c[k];
k-=lowbit(k);
}
return s;
}
int main()
{
int n;
ll s1,s2,s,cnt,ans;
while (~scanf("%d",&n))
{
s1=s2=cnt=0;
V.clear();
M.clear();
for (int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
V.push_back(a[i]);
}
sort(V.begin(),V.end());
V.erase(unique(V.begin(),V.end()),V.end());//去重,把整个区间内重复的数都当成一个数
for (int i=0;i<V.size();i++)
{
M[V[i]]=i+1;//给每个数重新编号
}
for (int i=1;i<=n;i++)
a[i]=M[a[i]];
memset(c,0,sizeof(c));
for (int i=1; i<=n; i++)
{
add(1,a[i]);
lmin[i]=sum(a[i]-1);//当前位置左边比他小的有多少个
lmax[i]=sum(N-1)-sum(a[i]);//已经出现的数肯定是他左边的数,在这个时候记录数轴上有多少个数再减去小于等于的,就是大于的了
}
memset(c,0,sizeof(c));
for (int i=n; i>=1; i--)
{
add(1,a[i]);
rmin[i]=sum(a[i]-1);
rmax[i]=sum(N-1)-sum(a[i]);
}
for (int i=1; i<=n; i++)
{
s1+=lmin[i];//升序的对数
s2+=lmax[i];//逆序的对数
}
s=s1*s2;
// cout<<s<<endl;
for (int i=1;i<=n;i++)
{
cnt+=lmax[i]*lmin[i]+rmax[i]*rmin[i]+lmax[i]*rmax[i]+lmin[i]*rmin[i];
}
//cout<<cnt<<endl;
ans=s-cnt;
printf ("%lld\n",ans);
}
return 0;
}
相关文章推荐
- (HDU 5792)2016 Multi-University Training Contest 5 World is Exploding (逆序数、顺序数、树状数组)
- HDU5792 World is Exploding(树状数组)2016 Multi-University Training Contest 5
- hdu 5792 World is Exploding 2016 Multi-University 5
- 2016 Multi-University Training Contest 5 1012 World is Exploding (数学+离散化)
- HDOJ 5792 (2016多校联合训练 Training Contest 5) World is Exploding
- hdu 5775 Bubble Sort(2016 Multi-University Training Contest 4——树状数组)
- 2016 Multi-University Training Contest 2 1005 hdu 5738 计算几何
- 2016 Multi-University Training Contest 1 C Game(hdu 5725)
- 2016 Multi-University Training Contest 1 1002 hdu 5724 博弈
- 2016 Multi-University Training Contest 1-1004---HDU 5726 GCD
- hdu 5734 Acperience 2016 Multi-University Training Contest 2
- HDU 5274 Chess(SG博弈)---2016 Multi-University Training Contest 1
- 2016 Multi-University Training Contest 1-1001---HDU 5723 Abandoned country(DFS+最小生成树)
- 2016 Multi-University Training Contest 2 hdu 5734 Acperience【推公式,数学】
- HDU 5724 Chess(2016 Multi-University Training Contest 1的1002题)
- 2016 Multi-University Training Contest 2 1001 hdu 5734 暴力
- HDU 5723 Abandoned country(2016 Multi-University Training Contest 1的1001题)
- 2016 Multi-University Training Contest 1 1011(HDU 5733 计算几何)
- HDU 5733 tetrahedron (2016 Multi-University Training Contest 1 计算几何)
- HDU 5738 Eureka (from: 2016 Multi-University Training Contest 2)