zoukankan      html  css  js  c++  java
  • BZOJ3295: [Cqoi2011]动态逆序对 莫队

    这个用莫队做会被卡,但是我还是......

    收获在于树状数组维护后缀和以及双维排序......

    莫队的时间复杂度比想象中的要好一些....

    然而我还是被卡了......

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define MAXN 100005
    using namespace std;
    int pos[MAXN],len,a[MAXN],front[MAXN],back[MAXN],n,m,t[MAXN],p,now,b[MAXN],live[MAXN];
    struct Q
    {
       int pos,time,ans;
    }q[MAXN];
    int comp(const Q x,const Q y)
    {
       return pos[x.pos]<pos[y.pos]||(pos[x.pos]==pos[y.pos]&&x.time<y.time);
    }
    int end_comp(const Q x,const Q y)
    {
       return x.time<y.time;
    }
    inline int lowbit(int x)
    {
       return x&(-x);
    }
    inline void update_front(int x,int i)
    {
       if(x==0)return;
       while(x>0)
       {
         front[x]+=i;
         x-=lowbit(x);
       }
    }
    inline void update_back(int x,int i)
    {
       if(x==0)return;
       while(x<=n)
       {
         back[x]+=i;
         x+=lowbit(x);  
       }
    }
    inline int sum_front(int x)
    {
       int ret=0;
       while(x<=n)
       {
         ret+=front[x];
         x+=lowbit(x);
       }
       return ret;
    }
    inline int sum_back(int x)
    {
       int ret=0;
       while(x>0)
       {
         ret+=back[x];
         x-=lowbit(x); 
       }
       return ret;
    }
    long long ans;
    void pre()
    {
        scanf("%d%d",&n,&m);
        len=(int)(sqrt(n+0.5));
        for(int i=1;i<=n;i++)
        {
          scanf("%d",&a[i]);
          live[a[i]]=i;
          pos[i]=(i-1)/len+1;
        }
        for(int i=n;i>0;i--)
        {
          ans+=sum_back(a[i]-1);
          update_back(a[i],1);
        }
        update_back(a[1],-1);
        p=1;
        now=1;
        for(int i=1;i<=m;i++)
        {
          scanf("%d",&b[i]);
          q[i].pos=live[b[i]];
          q[i].time=i;
        }
        sort(q+1,q+m+1,comp);
    }
    inline void via(int pl,int i)
    {
        a[live[pl]]=(i==1)?pl:0;
        if(live[pl]<p)update_front(pl,i);
        if(live[pl]>p)update_back(pl,i);
    }
    inline void do_front(int pl)
    {
        update_front(a[pl],1);
        update_back(a[pl+1],-1);
    }
    inline void do_back(int pl)
    {
        update_back(a[pl],1);
        update_front(a[pl-1],-1);
    }
    void work()
    {
        for(int i=1;i<=m;i++)
        {
           while(now<q[i].time)via(b[now++],-1);
           while(now>q[i].time)via(b[--now],1);
           while(p<q[i].pos)do_front(p++);
           while(p>q[i].pos)do_back(p--);
           q[i].ans=sum_front(a[q[i].pos]+1)+sum_back(a[q[i].pos]-1);
        }
    }
    void print()
    {
        sort(q+1,q+m+1,end_comp);
        for(int i=1;i<=m;i++)
        {
          printf("%lld
    ",ans);
          ans-=q[i].ans;
        }
    }
    int main()
    {
        //freopen("inverse.in","r",stdin);
        //freopen("inverse.out","w",stdout);
        pre();
        work();
        print();
        return 0;
    }
  • 相关阅读:
    aarch64_p1
    aarch64_o2
    aarch64_o1
    aarch64_n3
    aarch64_n2
    aarch64_n1
    aarch64_m3
    aarch64_m2
    aarch64_m1
    aarch64_l3
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7059848.html
Copyright © 2011-2022 走看看