【CF459D】 Pashmak and Parmida's problem [树状数组]

CF459D Pashmak and Parmida's problem

给出长度为n的序列a。

f(i,j,x)表示ai..aj中x的出现次数。

求有多少对i,j满足f(1,i,ai) > f(j,n,aj)。(i<j)

害挺水 就是开始计数那用的玄学vector超时了...

用 map/离散化预处理出 f(1, i, a[i]) 和 f(j, n, a[j]) 类似求逆序对,树状数组、维护

#include<bits/stdc++.h>
using namespace std;
#define Max(x,y) (x)>(y)?(x):(y)
#define Min(x,y) (x)<(y)?(x):(y)
#define ll long long
#define rg register
const int N=1e6+5,M=10000+5,inf=0x3f3f3f3f,P=9999973;
int n,a[N],c[N<<2],f1[N],f2[N];
ll ans=0;
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

int lowbit(int x){return x&(-x);}
void add(int pos,int add){
    while(pos<=n) c[pos]+=add,pos+=lowbit(pos);
}
ll query(int pos){
    ll ret=0;
    while(pos>0) ret+=c[pos],pos-=lowbit(pos);
    return ret;
}

int main(){
//    freopen("in.txt","r",stdin);
    rd(n);
    //b.clear();d.clear();
    for(int i=1;i<=n;++i) rd(a[i]);
    map<int,int>mp;
    for(int i=1;i<=n;i++) f1[i]=++mp[a[i]];
    mp.clear();
    for(int i=n;i;--i) f2[i]=++mp[a[i]],add(f2[i],1);
    for(int i=1;i<=n;++i){
        add(f2[i],-1);
        ans+=query(f1[i]-1);
    }
    printf("%lld",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/lxyyyy/p/11293888.html