• bzoj2141: 排队


    诶这这这这怎么又是树状数组和逆序对(快要被虐哭了55555)

    强行分块。。。

    我们先开block个权值树状数组,把每个块的值插进去,块里面的直接算,外面的靠树状数组

    if sum ++ -- 好烦。。

    然而对拍是个好东西。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int s[150][21000];
    int lowbit(int x){return x&-x;}
    void change(int x,int w,int k)
    {
        while(x<=20100)
        {
            s[w][x]+=k;
            x+=lowbit(x);
        }
    }
    int getsum(int x,int w)
    {
        int ret=0;
        while(x>0)
        {
            ret+=s[w][x];
            x-=lowbit(x);
        }
        return ret;
    }
    
    //----------bit------------------------
    
    int a[21000];
    int lslen,ls[21000];
    
    int block,st[21000];
    int main()
    {
        freopen("data.in","r",stdin);
        freopen("1.out","w",stdout);
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),ls[++lslen]=a[i];
        sort(ls+1,ls+lslen+1);
        lslen=unique(ls+1,ls+lslen+1)-ls-1;
        for(int i=1;i<=n;i++)
            a[i]=lower_bound(ls+1,ls+lslen+1,a[i])-ls;
        
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            sum+=(i-1-getsum(a[i],1));
            change(a[i],1,1);
        }
        memset(s[1],0,sizeof(s[1]));
        printf("%d
    ",sum);
        
        //--------sc&&LSH&&初始逆序对数----------------- 
        
        block=int(sqrt(double(n+1)));
        for(int i=1;i<=n;i++)
        {
            st[i]=(i-1)/block+1;
            change(a[i],st[i],1);
        }
        
        int Q,x,y;
        scanf("%d",&Q);
        while(Q--)
        {
            scanf("%d%d",&x,&y);
            if(x>y)swap(x,y);
            if(a[x]>a[y])sum--;
            if(a[x]<a[y])sum++;
            
            if(st[x]==st[y])
            {
                for(int i=x+1;i<=y-1;i++)
                {
                    if(a[x]>a[i])sum--;
                    if(a[x]<a[i])sum++;
                    if(a[y]>a[i])sum++;
                    if(a[y]<a[i])sum--;
                }
                swap(a[x],a[y]);
            }
            else
            {
                for(int i=x+1;i<=st[x]*block;i++)
                {
                    if(a[x]>a[i])sum--;
                    if(a[x]<a[i])sum++;
                    if(a[y]>a[i])sum++;
                    if(a[y]<a[i])sum--;
                }
                for(int i=(st[y]-1)*block+1;i<=y-1;i++)
                {
                    if(a[x]<a[i])sum++;
                    if(a[x]>a[i])sum--;
                    if(a[y]<a[i])sum--;
                    if(a[y]>a[i])sum++;
                }
                for(int i=st[x]+1;i<=st[y]-1;i++)
                {
                    sum-=getsum(a[x]-1,i);
                    sum+=block-getsum(a[x],i);
                    
                    sum+=getsum(a[y]-1,i);
                    sum-=block-getsum(a[y],i);
                }
                
                change(a[x],st[x],-1);
                change(a[y],st[y],-1);
                swap(a[x],a[y]);
                change(a[x],st[x],1);
                change(a[y],st[y],1);
            }
            printf("%d
    ",sum);
        }
        return 0;
    }
  • 相关阅读:
    快速幂(Fast Pow)
    半小时写完替罪羊重构点分树做动态动态点分治之紫荆花之恋的wyy贴心指导
    POJ2942 UVA1364 Knights of the Round Table 圆桌骑士
    二分图判定
    Tarjan求点双连通分量
    POJ1523 SPF 单点故障
    OI比赛常数优化
    Tarjan求割点
    NOIP2015 D1T1 神奇的幻方
    NOIP2016 D2T2 蚯蚓
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8877647.html
Copyright © 2020-2023  润新知