• bzoj3744 Gty的妹子序列


    Description

    我早已习惯你不在身边,
    人间四月天 寂寞断了弦。
    回望身后蓝天,跟再见说再见……
    某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现她们排成了一个序列,每个妹子有一个美丽度。
    Bakser神犇与他打算研究一下这个妹子序列,于是Bakser神犇问道:"你知道区间[l,r]中妹子们美丽度的逆序对数吗?"
    蒟蒻Autumn只会离线乱搞啊……但是Bakser神犇说道:"强制在线。"
    请你帮助一下Autumn吧。
    给定一个正整数序列a,对于每次询问,输出al...ar中的逆序对数,强制在线。

    Input

    第一行包括一个整数n(1<=n<=50000),表示数列a中的元素数。
    第二行包括n个整数a1...an(ai>0,保证ai在int内)。
    接下来一行包括一个整数m(1<=m<=50000),表示询问的个数。
    接下来m行,每行包括2个整数l、r(1<=l<=r<=n),表示询问al...ar中的逆序对数(若ai>aj且i<j,则为一个逆序对)。
    l,r要分别异或上一次询问的答案(lastans),最开始时lastans=0。
    保证涉及的所有数在int内。

    Output

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

    Sample Input

    4
    1 4 2 3
    1
    2 4

    Sample Output

    2

    正解:分块+树状数组+主席树。

    想$O(nsqrt{n})$的做法,想不出来。。然后看了一眼题解的复杂度。。

    $O(nsqrt{n}logn)$,这不是$mato$的文件管理那题的复杂度吗。。

    我真是蠢啊,离线做法都是这样的复杂度,在线怎么会更优秀。。

    然后就不是很难做了。

    首先,我们将序列分块以后可以预处理出$f[j][i]$,表示第$j$个点到第$i$个块右端点这段区间的逆序对数。这个用树状数组统计,复杂度是$O(nsqrt{n}logn)$的。

    然后,我们再把每个数弄到主席树上(等下会用到的)。

    询问的时候,如果$l$和$r$在同一个块上,我们直接用树状数组暴力统计这个区间的逆序对。

    如果$l$和$r$不在同一个块上,我们就把区间分开,$l$和$r$的前一个块的右端点分成一个区间,加上对应的$f$值。

    然后我们再暴力统计$r$这个块上属于这个区间的点与前面区间的逆序对数。那么我们要统计的就是$l-1$到$i-1$中大于$a[i]$的数的个数,这个就是用刚刚建好的主席树搞就行了。

    于是这道题我们就完美地解决了。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <complex>
     5 #include <cstring>
     6 #include <cstdlib>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <cmath>
    10 #include <queue>
    11 #include <stack>
    12 #include <map>
    13 #include <set>
    14 #define inf (1<<30)
    15 #define N (50010)
    16 #define il inline
    17 #define RG register
    18 #define ll long long
    19 #define lb(x) (x & -x)
    20 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    21 
    22 using namespace std;
    23 
    24 int sum[20*N],ls[20*N],rs[20*N],rt[N],sz;
    25 int f[N][230],c[N],a[N],hsh[N],n,m,tot;
    26 int LL[N],RR[N],bl[N],totb,block;
    27 ll ans;
    28 
    29 il int gi(){
    30     RG int x=0,q=1; RG char ch=getchar();
    31     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    32     if (ch=='-') q=-1,ch=getchar();
    33     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    34     return q*x;
    35 }
    36 
    37 il void add(RG int x,RG int v){ for (;x<=tot;x+=lb(x)) c[x]+=v; return; }
    38 
    39 il int query(RG int x){ RG int res=0; for (;x;x-=lb(x)) res+=c[x]; return res; }
    40 
    41 il void insert(RG int x,RG int &y,RG int l,RG int r,RG int v){
    42     sum[y=++sz]=sum[x]+1,ls[y]=ls[x],rs[y]=rs[x];
    43     if (l==r) return; RG int mid=(l+r)>>1;
    44     v<=mid?insert(ls[x],ls[y],l,mid,v):insert(rs[x],rs[y],mid+1,r,v);
    45 }
    46 
    47 il int querynxt(RG int x,RG int y,RG int l,RG int r,RG int v){
    48     if (l==r) return 0; RG int mid=(l+r)>>1;
    49     if (v<=mid) return querynxt(ls[x],ls[y],l,mid,v)+sum[rs[y]]-sum[rs[x]];
    50     else return querynxt(rs[x],rs[y],mid+1,r,v);
    51 }
    52 
    53 il void work(){
    54     n=gi(),block=sqrt(n),totb=(n-1)/block+1;
    55     for (RG int i=1;i<=n;++i){
    56     a[i]=gi(),hsh[++tot]=a[i],bl[i]=(i-1)/block+1;
    57     if (!LL[bl[i]]) LL[bl[i]]=i; RR[bl[i]]=i;
    58     }
    59     sort(hsh+1,hsh+tot+1),tot=unique(hsh+1,hsh+tot+1)-hsh-1;
    60     for (RG int i=1;i<=n;++i){
    61     a[i]=lower_bound(hsh+1,hsh+tot+1,a[i])-hsh;
    62     insert(rt[i-1],rt[i],1,tot,a[i]);
    63     }
    64     for (RG int i=1;i<=totb;++i){
    65     for (RG int j=RR[i];j;--j)
    66         f[j][i]=f[j+1][i]+query(a[j]-1),add(a[j],1);
    67     for (RG int j=RR[i];j;--j) add(a[j],-1);
    68     }
    69     m=gi(); RG int l,r;
    70     while (m--){
    71     l=gi()^ans,r=gi()^ans,ans=0;
    72     if (bl[l]==bl[r]){
    73         for (RG int i=l;i<=r;++i)
    74         ans+=query(tot)-query(a[i]),add(a[i],1);
    75         for (RG int i=l;i<=r;++i) add(a[i],-1);
    76     } else{
    77         ans=f[l][bl[r]-1];
    78         for (RG int i=LL[bl[r]];i<=r;++i)
    79         ans+=querynxt(rt[l-1],rt[i],1,tot,a[i]);
    80     }
    81     printf("%lld
    ",ans);
    82     }
    83     return;
    84 }
    85 
    86 int main(){
    87     File("gty");
    88     work();
    89     return 0;
    90 }
  • 相关阅读:
    工厂模式
    将WebApi Host到控制台和IIS
    模板方法模式
    策略模式
    插件式WebApi服务及自动生成Api帮助文档
    单例模式
    外观模式
    论文序号的结构层次顺序
    计算机面试之Session、Cookie、Token
    Django的日常操作
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6657407.html
Copyright © 2020-2023  润新知