Mn Zn 树套树求助
查看原帖
Mn Zn 树套树求助
125355
Mihari楼主2021/6/10 22:12

拿一道数据水的题打树套树,但是为什么下面的代码权值线段树 namespace sgtre 部分空间需要开大 2020 倍才能过啊?萌新想不明白 qwq\rm qwq.

#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;

#define NDEBUG
#include<cassert>

namespace Elaina{
    #define rep(i, l, r) for(int i=(l), i##_end_=(r); i<=i##_end_; ++i)
    #define drep(i, l, r) for(int i=(l), i##_end_=(r); i>=i##_end_; --i)
    #define fi first
    #define se second
    #define mp(a, b) make_pair(a, b)
    #define Endl putchar('\n')
    #define mmset(a, b) memset(a, b, sizeof a)
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
    template<class T>inline T fab(T x){ return x<0? -x: x; }
    template<class T>inline void getmin(T& x, const T rhs){ x=min(x, rhs); }
    template<class T>inline void getmax(T& x, const T rhs){ x=max(x, rhs); }
    template<class T>inline T readin(T x){
        x=0; int f=0; char c;
        while((c=getchar())<'0' || '9'<c) if(c=='-') f=1;
        for(x=(c^48); '0'<=(c=getchar()) && c<='9'; x=(x<<1)+(x<<3)+(c^48));
        return f? -x: x;
    }
    template<class T>inline void writc(T x, char s='\n'){
        static int fwri_sta[1005], fwri_ed=0;
        if(x<0) putchar('-'), x=-x;
        do fwri_sta[++fwri_ed]=x%10, x/=10; while(x);
        while(putchar(fwri_sta[fwri_ed--]^48), fwri_ed);
        putchar(s);
    }
}
using namespace Elaina;

const int maxn=2e4;
const int maxm=2e3;
const int loga=30;
const int maxc=(maxn+maxm)*20;

namespace sgtre{
    int ls[maxc*loga+5], rs[maxc*loga+5], c[maxc*loga+5], ncnt;
    #define mid ((l+r)>>1)
    void modify(int& i, int l, int r, int x, int delta){
        c[i==0? (i=++ncnt): i]+=delta;
        assert(ncnt<=maxc*loga);
        if(l==r) return;
        if(x<=mid) modify(ls[i], l, mid, x, delta);
        else modify(rs[i], mid+1, r, x, delta);
    }
    int query(int i, int l, int r, int L, int R){
        if(!i || L>R) return 0;
        if(L<=l && r<=R) return c[i];
        int ret=0;
        if(L<=mid) ret+=query(ls[i], l, mid, L, R);
        if(mid<R) ret+=query(rs[i], mid+1, r, L, R);
        return ret;
    }
    #undef mid
}

namespace saya{
    #define __i (((l)+(r))|((l)!=(r)))
    #define mid ((l+r)>>1)
    int rt[maxn<<1|1];
    void modify(int l, int r, int i, int x, int delta){
        sgtre::modify(rt[__i], 1, 1e9, x, delta);
        if(l==r) return;
        if(i<=mid) modify(l, mid, i, x, delta);
        else modify(mid+1, r, i, x, delta);
    }
    int query(int l, int r, int L, int R, int xl, int xr){
        if(L>R) return 0;
        if(L<=l && r<=R) return sgtre::query(rt[__i], 1, 1e9, xl, xr);
        int ret=0;
        if(L<=mid) ret+=query(l, mid, L, R, xl, xr);
        if(mid<R) ret+=query(mid+1, r, L, R, xl, xr);
        return ret;
    }
    #undef __i
    #undef mid
}

int h[maxn+5], n, ans;

inline void input(){
    n=readin(1);
    rep(i, 1, n){
        h[i]=readin(1);
        saya::modify(1, n, i, h[i], 1);
    }
    rep(i, 1, n) ans+=saya::query(1, n, i+1, n, 1, h[i]-1);
}

signed main(){
    input();
    writc(ans);
    int m=readin(1), a, b;
    while(m--){
        a=readin(1), b=readin(1);
        if(a>b) swap(a, b);
        ans-=saya::query(1, n, a+1, b-1, 1, h[a]-1);
        ans-=saya::query(1, n, a+1, b-1, h[b]+1, 1e9);
        if(h[a]>h[b]) --ans;
        saya::modify(1, n, a, h[a], -1);
        saya::modify(1, n, b, h[b], -1);
        swap(h[a], h[b]);
        saya::modify(1, n, a, h[a], 1);
        saya::modify(1, n, b, h[b], 1);
        ans+=saya::query(1, n, a+1, b-1, 1, h[a]-1);
        ans+=saya::query(1, n, a+1, b-1, h[b]+1, 1e9);
        if(h[a]>h[b]) ++ans;
        writc(ans);
    }
    return 0;
}
2021/6/10 22:12
加载中...