【樹狀陣列】五元組問題
阿新 • • 發佈:2020-08-03
Description
給定n個數字,組成數字串 A1, A2, …, An。
五元組{ i, j, k, s, t }滿足以下兩個條件:
a) 1 ≤ i < j < k < s < t ≤ n
b) Ai < Aj < Ak < As < At
例如,數字串{2, 1, 3, 4, 5, 7, 6}中,包含以下4個五元組{1, 3, 4, 5, 6}, {2, 3, 4, 5, 6}, {1, 3, 4, 5, 7} 和 {2, 3, 4, 5, 7}。
求給定數字串所包含的五元組的個數。
Input
第一行一個整數n(1≤n≤50,000),表示數字串包含n個數字。
第二行包括n個數字A1, A2, …, An(1≤Ai≤1,000,000)。
Output
輸出一行一個整數,表示五元組的個數。
Sample Input
【樣例1】
5
1 2 3 4 5
【樣例2】
7
2 1 3 4 5 7 6
【樣例3】
7
1 2 3 4 5 6 7
Sample Output
【樣例1】
1
【樣例2】
4
【樣例3】
21
思路
- 開long long+高精度
- 求二元組的數量,再用這個數量求三元組數量,以此類推
程式碼
#include <iostream> #include <cstdio> #include <cstring> #define maxn 50005 #define int long long using namespace std; int n,a[maxn],c[1000005],ans[50]; long long f[maxn]; int lowbit(int x){return x&(-x);} void add(int x,int d){for(int i=x;i<=1000000;i+=lowbit(i)) c[i]+=d;} long long ask(int x) { long long ans=0; for(int i=x;i;i-=lowbit(i)) ans+=c[i]; return ans; } void jia(int a[],int b[]) { if(a[0]<b[0]) a[0]=b[0]; for(int i=1;i<=a[0];++i) a[i]+=b[i]; for(int i=1;i<=a[0];++i) a[i+1]+=a[i]/10,a[i]%=10; if(a[a[0]+1]>0) ++a[0]; } void print(int a[]) { if(a[0]==0) printf("0\n"); for(int i=a[0];i;--i) cout<<a[i]; } signed main() { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]),f[i]=1; for(int i=2;i<=5;++i)//求i元組 { memset(c,0,sizeof(c)); add(a[i-1],f[i-1]); f[i-1]=0; for(int j=i;j<=n;++j) add(a[j],f[j]),f[j]=ask(a[j]-1); } for(int i=5;i<=n;++i)//高精度f[i]之和 { int temp[50]; memset(temp,0,sizeof(temp)); while(f[i]>0) temp[++temp[0]]=f[i]%10,f[i]/=10; jia(ans,temp); } print(ans); return 0; }