AT_abc436_f
前言
一道小清新的计数题。
前置知识:树状数组,扫描线。
分析
发现一种集合可以有多种方式来拍,思考如何才能不重不漏。
我的办法是把在值域上从小到大做扫描线,每个集合在其最大权值
则此时亮度限制就是
由于不能统计之前统计过的集合,我们只用考虑包含最大
为了得到包含
树状数组维护
时间复杂度
空间复杂度
:::info[Code]
#include <bits/stdc++.h>
using namespace std;
inline int read(){
int d=0,f=0;char ch=getchar();
while (!isdigit(ch)) f|=(ch=='-'),ch=getchar();
while (isdigit(ch)) d=d*10+ch-'0',ch=getchar();
return f?-d:d;
}
const int N=500005;
int n,b[N];
struct BIT{
int c[N];
inline void add(int x,int v){
for (int i=x;i<=n;i+=i&-i) c[i]+=v;
}
inline int query(int x){
int res=0;
for (int i=x;i;i-=i&-i) res+=c[i];
return res;
}
inline int query(int l,int r) {return query(r)-query(l-1);}
}tree;
int main(){
n=read();
for (int i=1;i<=n;i++) b[read()]=i;
long long ans=0;
for (int i=1;i<=n;i++){
tree.add(b[i],1);
ans+=1ll*tree.query(1,b[i])*tree.query(b[i],n);
}
printf("%lld\n",ans);
return 0;
}
:::
求赞 QWQ。