展开
题目描述
Erwin 最近对一种叫 thair 的东西巨感兴趣。。。
在含有 nn 个整数的序列 a1,a2,....an 中,三个数被称作thair当且仅当 i<j<k且 ai<aj<ak
求一个序列中 thair 的个数。
输入格式
开始一行一个正整数 nn,
以后一行 nn 个整数 a1,a2,...,an
输出格式
一行一个整数表示 thair 的个数。
数据规模与约定
- 对于 30\%30% 的数据 保证 n\le100n≤100;
- 对于 60\%60% 的数据 保证 n\le2000n≤2000;
- 对于 100\%100% 的数据 保证 1 \leq n\le3\times10^41≤n≤3×104,0\le a_i\lt 10^50≤ai<105。
做法
这里采用的做法
,首先我们先对题目分析统计三元上升组的个数 ,得到对于一个数
记录左边比他小的数的个数,右边比它大的数的个数。乘法原理,我们用两个树状数组来维护左边比他小的,和右边比它大的。
对于左边比他小的,只需要统计(val -1)的树状数组的前缀和,对于右边比它大的,只需要统计 n-i-(v-1)//除掉本身外比v大的数的个数,最后再扫描一遍乘法原理计数
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> #define re register #define fi first #define se second #define endl '\n' #define int long long #define wrn puts("NO") #define wry puts("YES") #define bug(x) cout<<#x<<"=="<<x<<endl #define fast_oi ios::sync_with_stdio(false);cin.tie(0) using namespace std; typedef pair<int,int>PII; typedef long long ll; typedef unsigned long long ull; const int N=3e4+5;//注意数组大小 const int INF=0x3f3f3f3f; const int mod=; ll qpow(ll a, ll b) {ll res = 1;while(b) {if(b & 1) res = (res * a) % mod;a = (a * a) % mod;b >>= 1;}return res%mod;} inline ll read() { ll x=0,w=1; char c=getchar(); while(c<'0'||c>'9') {if(c=='-') w=-1; c=getchar();} while(c<='9'&&c>='0') x=(x<<1)+(x<<3)+c-'0',c=getchar(); return w==1?x:-x; } inline void write(ll x) { if(x>=10) write(x/10); putchar(x%10+'0'); } inline ll lowbit(ll x) { return x&(-x); } template<class T> struct BT{//Fenwick tree T *a;int size; BT(int n){ size=n; a=new int[n+3]; memset(a,0,sizeof(int)*(n+2)); } ~BT(){delete []a;} void add(int i,T v){ while (i<=size) a[i]+=v,i+=lowbit(i); } T sum(int i){ T ans=0; while (i) ans+=a[i],i-=lowbit(i); return ans; } }; int n,a[N],b[N],m; int pos[N],dp[N]; int l[N],r[N]; void solverun() { n = read(); for (int i = 1; i <= n; i++) { a[i] = read(); b[i] = a[i]; } sort(b + 1 , b + 1 + n); m = unique(b + 1, b + 1 + n) - b - 1; BT<int>c(m); BT<int>d(m); //枚举中间结点 找出左边结点个数 右边结点个数 再用乘法原理 for (int i = 1; i <= n; ++i) { int p = lower_bound(b + 1, b + 1 + m , a[i]) - b; c.add(p,1); l[i]=c.sum(p - 1); } for (int i = n; i >= 1; i--) { int p = lower_bound(b + 1, b + 1 + m, a[i]) - b; d.add(p,1); r[i] = n - i - (d.sum(p) - 1); // sum - 1 是小于等于b[i](除掉本身的个数) } //乘法原理 ll res = 0; for (int i = 2; i < n; i++) { res += 1ll * l[i] * r[i]; } cout << res << endl; } signed main() { #ifdef ONLINE_JUDGE #else freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif fast_oi; int cas = 1; // cin >> cas; while (cas--) { solverun(); } return 0; }
讯享网

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/49736.html