zoukankan      html  css  js  c++  java
  • 【题解】「Ynoi2019模拟赛」Yuno loves sqrt technology II [*medium]

    考虑莫队。

    如果是单纯的莫队的话,还需要一个树状数组来维护逆序对数,这样子的话复杂度是 (O(n^{1.5}log n)),难以接受。

    怎么将这个树状数组消除?

    考虑当前区间为 ([l,r-1]) ,需要将右端点向右移动,即加入 (a_r) ,并且将答案加上 (a_{l,l+1,cdots,r-1}) 中大于 (a_r) 的数的个数。其实这也就等于 (a_{1cdots r-1}) 中大于 (a_r) 的个数减去 (a_{1cdots l-1}) 中大于 (a_r) 的个数。

    第一个贡献可以直接将整个数组扫一遍处理,时间复杂度 (O(nlog n))

    第二个询问的话,考虑将 (l-1) 处开个桶,然后将 (r) 丢入。因为莫队的移动次数是 (O(nsqrt{m})) 的,因此空间的需求量也是 (O(nsqrt{m})) 的。

    最后只需要枚举左端点,然后获取其桶中的数的答案即可。

    但是这题卡空间,不能直接存储贡献。同时可以发现一个 (l) 对应的一段 (r) 其实是连续的,因此直接将区间做右端点存下即可。

    注意 ans 记录的是答案变化量,因此最终还需要做一遍前缀和。

    (其实就是相当于将莫队的转移再次离线

    // #define debug
    
    const int N=1e5+5;
    
    int n,m,_,a[N];
    ll ans[N];
    struct Query {int l,r,id;} q[N];
    
    // {{{ unique_a
    inline void unique_a() {
        static int h[N];
        lep(i,1,n) h[i]=a[i];
        std::sort(h+1,h+1+n),_=1;
        lep(i,2,n) if(h[_]!=h[i]) h[++_]=h[i];
        lep(i,1,n) a[i]=std::lower_bound(h+1,h+1+_,a[i])-h;
    }
    // }}}
    
    namespace Get_Pre { // {{{
    ll pre[N],suf[N];
    
    // {{{ BIT
    int res,c[N];
    inline int lowbit(int x) {return x&(-x);}
    inline void modify(int x) {for(;x<=_;x+=lowbit(x)) ++c[x];}
    inline int query(int x) {res=0; for(;x;x-=lowbit(x)) res+=c[x]; return res;}
    inline void clear() {CLEAR(c);}
    // }}}
    
    inline void solve() {
        clear(); lep(i,1,n) pre[i]=pre[i-1]+query(_-a[i]),modify(_-a[i]+1);
        clear(); rep(i,n,1) suf[i]=suf[i+1]+query(a[i]-1),modify(a[i]);
    }
    } using Get_Pre::pre,Get_Pre::suf; // }}}
    
    // {{{ Solve
    struct Node {int l,r,id,typ;};
    std::vector <Node> sta1[N],sta2[N];
    
    // {{{ Block
    const int SqrtN=4e2+5;
    int id[N],val[N],L[SqrtN],R[SqrtN],sum[SqrtN];
    
    inline int query(int x) {return val[x]+sum[id[x]];}
    inline void update1(int x) {
        lep(i,L[id[x]],x-1) ++val[i];
        lep(i,1,id[x]-1) ++sum[i];
    }
    inline void update2(int x) {
        lep(i,x+1,R[id[x]]) ++val[i];
        lep(i,id[x]+1,id[_]) ++sum[i];
    }
    inline void clear() {CLEAR(val),CLEAR(sum);}
    // }}}
    
    inline void solve() {
        int B=sqrt(_);
        for(int l=1,r=0,c=1;l<=_;l=r+1,++c) {
            r=min(l+B-1,_),L[c]=l,R[c]=r;
            lep(i,l,r) id[i]=c;
        }
    
        clear(); lep(i,1,n) {
            update1(a[i]);
            for(Node now:sta1[i]) lep(j,now.l,now.r) ans[now.id]+=1ll*query(a[j])*now.typ;
        }
        clear(); rep(i,n,1) {
            update2(a[i]);
            for(Node now:sta2[i]) lep(j,now.l,now.r) ans[now.id]+=1ll*query(a[j])*now.typ;
        }
    }
    // }}}
    
    int pos[N];
    int main() {
        IN(n,m);
        lep(i,1,n) IN(a[i]);
        lep(i,1,m) IN(q[i].l,q[i].r),q[i].id=i;
    
        unique_a();
        Get_Pre::solve();
    
        #ifdef debug
        printf("a : "); lep(i,1,n) printf("%d ",a[i]); puts("");
        printf("pre : "); lep(i,1,n) printf("%lld ",pre[i]); puts("");
        printf("suf : "); lep(i,1,n) printf("%lld ",suf[i]); puts("");
        #endif
    
        int B=n/sqrt(m*2/3+1);
        std::sort(q+1,q+1+m,[&](Query x,Query y){return (x.l/B)^(y.l/B)?x.l<y.l:x.r<y.r;});
        lep(i,1,m) pos[q[i].id]=i;
    
        int l=1,r=0;
        lep(i,1,m) {
            if(r<q[i].r) ans[i]+=(pre[q[i].r]-pre[r]),sta1[l-1].pb((Node){r+1,q[i].r,i,-1}),r=q[i].r;
            if(r>q[i].r) ans[i]-=(pre[r]-pre[q[i].r]),sta1[l-1].pb((Node){q[i].r+1,r,i,1}),r=q[i].r;
            if(l<q[i].l) ans[i]-=(suf[l]-suf[q[i].l]),sta2[r+1].pb((Node){l,q[i].l-1,i,1}),l=q[i].l;
            if(l>q[i].l) ans[i]+=(suf[q[i].l]-suf[l]),sta2[r+1].pb((Node){q[i].l,l-1,i,-1}),l=q[i].l;
        }
    
        solve();
        lep(i,1,m) ans[i]+=ans[i-1];
        lep(i,1,m) printf("%lld
    ",ans[pos[i]]);
        return 0;
    }
    
  • 相关阅读:
    [BZOJ3513] idiots
    2020牛客暑期多校训练营(第六场)A
    2020牛客暑期多校训练营(第六场)J
    2020牛客暑期多校训练营(第六场)H
    2020牛客暑期多校训练营(第六场)G
    2020牛客暑期多校训练营(第六场)K
    组队训练日志 2020.10.05
    Java基础
    Auditd
    Snort记录
  • 原文地址:https://www.cnblogs.com/losermoonlights/p/14165847.html
Copyright © 2011-2022 走看看