• BZOJ3787:Gty的文艺妹子序列(分块,树状数组)


    Description

    Autumn终于会求区间逆序对了!Bakser神犇决定再考验一下他,他说道:
    “在Gty的妹子序列里,某个妹子的美丽度可也是会变化的呢。你还能求出某个区间中妹子们美丽度的逆序对数吗?当然,为了方便,这次我们规定妹子们的美丽度在[1,n]中。仍然强制在线。”
    Autumn需要你的帮助。
    给定一个正整数序列a(1<=ai<=n),支持单点修改,对于每次询问,输出al...ar中的逆序对数,强制在线。

    Input

    第一行包括一个整数n(1<=n<=50000),表示数列a中的元素数。
    第二行包括n个整数a1...an(1<=ai<=n)。
    接下来一行包括一个整数m(1<=m<=50000),表示操作的个数。
    接下来m行,每行包括3个整数。
    0 L R (1<=L<=R<=n) 询问[L,R]中的逆序对数。
    1 p v (1<=p<=n,1<=v<=n) 将p位置的数修改为v。
    L,R,p,v 都需要异或上一次的答案,保证异或之后的值是合法的。
    保证涉及的所有数在int内。

    Output

    对每个询问,单独输出一行,表示al...ar中的逆序对数。对每个询问,单独输出一行,表示al...ar中的逆序对数。

    Sample Input

    10
    1 7 5 6 9 4 9 4 4 7
    10
    0 4 6
    0 5 8
    0 1 10
    1 25 19
    0 19 25
    1 14 4
    0 12 12
    0 2 5
    1 8 7
    1 1 10

    Sample Output

    2
    3
    16
    13
    0
    2

    Solution

    分块,同时维护几个数组:

    $f[i]$表示第$i$块内部的逆序对个数。

    $g[i][j]$表示第$i$块和第$j$块能形成的逆序对个数,第二维用树状数组维护。

    $s[i][j]$表示前$i$块里$j$数出现的次数,第二维同样用树状数组维护。

    查询就利用这三个数组查一下,利用好树状数组前缀和的性质。乱七八糟加加减减。

    修改就维护好这三个数组就好了……

    速度倒数第二$46s$低空飞过……心情简单……

    Code

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #define N (50009)
      6 #define S (259)
      7 using namespace std;
      8 
      9 int n,m,opt,l,r,ans,num,f[S],a[N];
     10 int ID[N],L[S],R[S];
     11 
     12 inline int read()
     13 {
     14     int x=0,w=1; char c=getchar();
     15     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
     16     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
     17     return x*w;
     18 }
     19 
     20 struct BIT
     21 {
     22     int c[N];
     23     void Update(int x,int v)
     24     {
     25         for (; x<=n; c[x]+=v,x+=(x&-x));
     26     }
     27     int Query(int x)
     28     {
     29         int ans=0;
     30         for (; x; ans+=c[x],x-=(x&-x));
     31         return ans;
     32     }
     33 }B,g[S],s[S];
     34 
     35 void Build()
     36 {
     37     int unit=sqrt(n);
     38     num=n/unit+(n%unit!=0);
     39     for (int i=1; i<=num; ++i)
     40         L[i]=(i-1)*unit+1, R[i]=i*unit;
     41     R[num]=n;
     42     for (int i=1; i<=num; ++i)
     43         for (int j=L[i]; j<=R[i]; ++j) ID[j]=i;
     44 }
     45 
     46 void Preprocess()
     47 {
     48     for (int i=1; i<=num; ++i)
     49     {
     50         for (int j=L[i]; j<=R[i]; ++j)
     51         {
     52             f[i]+=B.Query(n)-B.Query(a[j]);
     53             B.Update(a[j],1);
     54         }
     55         for (int j=L[i]; j<=R[i]; ++j) B.Update(a[j],-1);
     56     }
     57     for (int i=2; i<=num; ++i)
     58         for (int j=1; j<=i-1; ++j)
     59         {
     60             for (int k=L[j]; k<=R[j]; ++k) B.Update(a[k],1);
     61             for (int k=L[i]; k<=R[i]; ++k) g[i].Update(j,B.Query(n)-B.Query(a[k]));
     62             for (int k=L[j]; k<=R[j]; ++k) B.Update(a[k],-1);
     63         }
     64     for (int i=1; i<=num; ++i)
     65         for (int j=L[i]; j<=R[i]; ++j) s[i].Update(a[j],1);
     66     for (int i=2; i<=num; ++i)
     67         for (int j=1; j<=n; ++j) s[i].Update(j,s[i-1].Query(j)-s[i-1].Query(j-1));
     68 }
     69 
     70 int Calc(int l,int r)
     71 {
     72     int ans=0;
     73     if (ID[l]==ID[r])
     74     {
     75         for (int i=l; i<=r; ++i)
     76         {
     77             ans+=B.Query(n)-B.Query(a[i]);
     78             B.Update(a[i],1);
     79         }
     80         for (int i=l; i<=r; ++i) B.Update(a[i],-1);
     81         return ans;
     82     }
     83     for (int i=l; i<=R[ID[l]]; ++i)
     84     {
     85         ans+=s[ID[r]-1].Query(a[i]-1)-s[ID[l]].Query(a[i]-1);
     86         ans+=B.Query(n)-B.Query(a[i]);
     87         B.Update(a[i],1);
     88     }
     89     for (int i=l; i<=R[ID[l]]; ++i) B.Update(a[i],-1);
     90     
     91     for (int i=L[ID[r]]; i<=r; ++i)
     92     {
     93         ans+=(s[ID[r]-1].Query(n)-s[ID[r]-1].Query(a[i]))-(s[ID[l]].Query(n)-s[ID[l]].Query(a[i]));
     94         ans+=B.Query(n)-B.Query(a[i]);
     95         B.Update(a[i],1);
     96     }
     97     for (int i=L[ID[r]]; i<=r; ++i) B.Update(a[i],-1);
     98     
     99     for (int i=ID[l]+1; i<=ID[r]-1; ++i) ans+=f[i];
    100     for (int i=ID[l]+2; i<=ID[r]-1; ++i)
    101         ans+=g[i].Query(i-1)-g[i].Query(ID[l]);
    102     for (int i=l; i<=R[ID[l]]; ++i) B.Update(a[i],1);
    103     for (int i=L[ID[r]]; i<=r; ++i) ans+=B.Query(n)-B.Query(a[i]);
    104     for (int i=l; i<=R[ID[l]]; ++i) B.Update(a[i],-1);
    105     return ans;
    106 }
    107 
    108 void Change(int x,int k)
    109 {
    110     int id=ID[x];
    111     for (int i=id; i<=num; ++i) s[i].Update(a[x],-1);
    112     for (int i=id; i<=num; ++i) s[i].Update(k,1);
    113     
    114     for (int i=1; i<=id-1; ++i)
    115     {
    116         g[id].Update(i,-s[i].Query(n)+s[i].Query(a[x])+s[i-1].Query(n)-s[i-1].Query(a[x]));
    117         g[id].Update(i,s[i].Query(n)-s[i].Query(k)-s[i-1].Query(n)+s[i-1].Query(k));
    118     }
    119     for (int i=id+1; i<=num; ++i)
    120     {
    121         g[i].Update(id,-s[i].Query(a[x]-1)+s[i-1].Query(a[x]-1));
    122         g[i].Update(id,s[i].Query(k-1)-s[i-1].Query(k-1));
    123     }
    124     
    125     f[id]=0; a[x]=k;
    126     for (int i=L[id]; i<=R[id]; ++i)
    127     {
    128         f[id]+=B.Query(n)-B.Query(a[i]);
    129         B.Update(a[i],1);
    130     }
    131     for (int i=L[id]; i<=R[id]; ++i) B.Update(a[i],-1);
    132 }
    133 
    134 int main()
    135 {
    136     n=read();
    137     Build();
    138     for (int i=1; i<=n; ++i) a[i]=read();
    139     Preprocess();
    140     m=read();
    141     while (m--)
    142     {
    143         opt=read(); l=read(); r=read();
    144         l^=ans; r^=ans;
    145         if (opt==0) printf("%d
    ",ans=Calc(l,r));
    146         else Change(l,r);
    147     }
    148 }
  • 相关阅读:
    粉丝投稿!从2月份的面试被拒到如今的阿里P7,说一说自己学java以来的经验!
    深入浅出!阿里P7架构师带你分析ArrayList集合源码,建议是先收藏再看!
    简单梳理一下Redis实现分布式Session,建议做java开发的都看看!
    HashMap知识点总结,这一篇算是总结的不错的了,建议看看!
    面试官:小伙子,够了够了,一个工厂模式你都在这说半个小时了!
    iOS-----推送机制(下)
    iOS-----推送机制(上)
    iOS-----使用CoreLocation定位
    iOS-----使用AFNetworking实现网络通信
    iOS-----JSON解析
  • 原文地址:https://www.cnblogs.com/refun/p/10366972.html
Copyright © 2020-2023  润新知