[解説] LuoguP6185 [NOIオンライン改善グループ]列

これは、結論の問題です......

あなたは数回手バブルを再生した後、あなたは非常に有用な性質があります。

次の順序\(C [I] \)を表し(I \)\、次いで逆の数が彼のより少ない数の大きいの前にある\(\ sum_ {i = 1 } ^ NC [I] \) 。

バブルを考えてみましょう、すべての\(C [i]とは、\)確かに減少します(\ 1)\、とだけ減少します\(1 \)

次に\(K \)発泡が少ない時間を過ごした後\(K \)\(C [I]は、\)、蒸発させ、限り、我々が考慮するとして\([K + 1、N ] \) このセクションでの\(C [i]が\)答えは

\ [\(合計\ limits_ {K + 1 \ルC [I]} C [I] \右\)左 - \和\ limits_ {C [I] \ GE K + 1} K \]

それだけで罰金2つのフェンウィックツリーのメンテナンスをオープンしました。

ローカル交換操作は話を分類しました。

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;++i)
#define per(i,a,n) for (int i=n-1;i>=a;--i)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
typedef double db;
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;

const int N=2e5+10;

struct BIT {
    ll c[N]; int n;

    void init(int sz) {n=sz;rep(i,0,n+1) c[i]=0;}

    ll qwq(int x) {
        ll ans=0; for(;x;x-=x&-x) ans+=c[x];
        return ans;
    }
    ll qry(int l,int r) {return qwq(r)-qwq(l-1);}
    void upd(int x,ll v=1) {if(x!=0) for(;x<=n;x+=x&-x) c[x]+=v;}
}bt[2];

void upd(int x,int v=1) {bt[0].upd(x,v),bt[1].upd(x,v*x);}
void qry(int l,int r,ll &c1,ll &c2) {c1=bt[0].qry(l,r),c2=bt[1].qry(l,r);}

int n,m,a[N],cc[N];

int main() {
#ifdef LOCAL
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
#endif
    scanf("%d%d",&n,&m);
    rep(i,1,n+1) scanf("%d",&a[i]);
    bt[0].init(n);
    rep(i,1,n+1) {
        cc[i]=i-bt[0].qwq(a[i])-1;
        bt[0].upd(a[i]);
    }
    bt[0].init(n),bt[1].init(n);
    rep(i,1,n+1) upd(cc[i]);
    while(m--) {
        int opt,x; scanf("%d%d",&opt,&x);
        if(opt==2) {
            if(x>=n) {puts("0");continue;}
            ll t1,t2;
            qry(x+1,n,t1,t2);
            printf("%lld\n",t2-x*t1);
        } else {
            upd(cc[x],-1),upd(cc[x+1],-1);  // 先把贡献去掉
            if(a[x]>a[x+1]) --cc[x+1]; else ++cc[x]; // 分类讨论
            swap(cc[x],cc[x+1]),swap(a[x],a[x+1]);
            upd(cc[x],1),upd(cc[x+1],1);  // 再加回去
        }
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/wxq1229/p/12434715.html