abc--276--F

知识点

1.用树状数组维护比他小的数的个数
2.用树状数组维护前缀和
PS:可以用线段树,但没必要。注意取模。

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=998244353;
const int M=2e5+5;
//两个树状数组,一个求比他小的数的个数,一个球比他大的数的和

int kpow(int a,int b) {
    int ans=1;
    while(b) {
        if(b&1)ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}

int lowbit(int x) {
    return x&-x;
}

int n,a[M];
int c1[M],c2[M];

void up(int i,int v,int n=2e5) {
    while(i<=n) {
        c1[i]++;
        c2[i]=(c2[i]+v)%mod;
        i+=lowbit(i);
    }
}

int query(int c[],int i) {
    int sum=0;
    while(i) {
        sum=(sum+c[i])%mod;
        i-=lowbit(i);
    }
    return sum;
}
//期望诈骗题
//应该是精度有错误

signed main() {
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    int ans=0;
    for(int i=1;i<=n;i++) {
        //查询比他小的数的个数
        int t1=query(c1,a[i]-1)*2%mod*a[i]%mod;//比他小的数的个数
        int t2=(query(c2,2e5)-query(c2,a[i]-1)+mod)%mod*2%mod;//比他大的数的和
        ans=(ans+t1+t2+a[i])%mod;
        cout<<(ans*kpow(i*i%mod,mod-2)%mod)<<endl;
        up(a[i],a[i]);
    }
    return 0;
}
posted @ 2022-12-23 15:37  basicecho  阅读(29)  评论(0)    收藏  举报