[TIOJ]1694. Problem D 你的重生之旅

題目連結:http://tioj.infor.org/problems/1694

題目要求區間的逆序數對量,可以寫莫隊,並用BIT維護[L+-1,R+-1]的情況。
我因為ans[]只開到23000而吃了7次MLEQQ
#include <iostream>
#include <algorithm>
#include <cmath>
#include <bitset>
#include <queue>
#include <vector>
#define lld long long
#define PB push_back
#define F first
#define S second
#define jizz cin.tie(0);ios_base::sync_with_stdio(0);
#define endl '\n'
#define N 23000
using namespace std;
typedef pair<int,int> Pair;
int a[N+5],n,Q,cur_ans;
int ans[200005];
struct Query{
    int l,r,id,Lid;
    bool operator<(const Query &x)const{
        return Lid == x.Lid ? r < x.r : Lid < x.Lid;
    }
}q[200005];
struct BIT{
    int b[N+5];
    void update(int x,int e){
        while(x <= n){
            b[x]+=e;
            x += x&-x;
        }
    }
    int query(int x){
        int tmp = 0;
        while(x){
            tmp += b[x];
            x -= x&-x;
        }
        return tmp;
    }
}B;
void add(int x,bool wh){
    if(wh)cur_ans += B.query(n)-B.query(x);
    else cur_ans += B.query(x-1);
    B.update(x,1);
}
void sub(int x,bool wh){
    if(wh) cur_ans -= B.query(n)-B.query(x);
    else cur_ans -= B.query(x-1);
    B.update(x,-1);
}
void MO(){
    sort(q,q+Q);
    B.update(a[1],1);
    for(int i = 0,L = 1,R = 1; i < Q ; i++){
        while(R < q[i].r) add(a[++R],1);
        while(L > q[i].l) add(a[--L],0);
        while(L < q[i].l) sub(a[L++],0);
        while(R > q[i].r) sub(a[R--],1);
        ans[q[i].id] = cur_ans;
    }
    for(int i = 0 ; i < Q ; i++)cout << ans[i] << endl;
}
int main(){jizz
    cin >> n >> Q;
    for(int i = 1; i <= n ; i++)cin >> a[i];
    int K = 1+sqrt(n);
    for(int i = 0 ; i < Q; i++){
        cin >> q[i].l >> q[i].r;
        q[i].id = i;
        q[i].Lid = q[i].l/K;
    }
    MO();
    return 0;
}


留言

這個網誌中的熱門文章

[TIOJ]1617. [Interactive] 中位數

[TIOJ]1337. 隕石

[TIOJ]1994. 冰塊線