zoukankan      html  css  js  c++  java
  • bzoj 3744: 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(m√nlogn),在线显然不会更优
    所以把数列分块
    令f[j][i]表示j~第i块右端所含的逆序对数
    pos[i]表示第i为属于第几块
    查询时有2种情况:
    1.在同一块,直接枚举,用树状数组
    2.不再同一块,那么我们可以把[l,r]分成2块,分开解决
    首先是[l,x=在r前面的块右端点],直接答案+f[l][pos[x]]
    之后考虑[x+1,r]与[l,x]的逆序对数和[x+1,r]自己含有的逆序对数
    后者像第1种情况用树状数组
    前者枚举i=[l,x],建一棵主席树求大于a[i]的数量
    每一次查询复杂度O(√nlogn)
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 using namespace std;
      7 int n,c1[50001],c2[50001],tot;
      8 int ch[5000001][2],sum[5000001],a[50001],d[50001],siz,lim,bl[1001],br[1001],cnt;
      9 int pos[50001],f[50001][301],root[50001],ans,m;
     10 void add1(int x,int d)
     11 {
     12   while (x<=n)
     13     {
     14       c1[x]+=d;
     15       x+=(x&(-x));
     16     }
     17 }
     18 void add2(int x,int d)
     19 {
     20   while (x)
     21     {
     22       c2[x]+=d;
     23       x-=(x&(-x));
     24     }
     25 }
     26 int query1(int x)
     27 {
     28   int s=0;
     29   while (x)
     30     {
     31       s+=c1[x];
     32       x-=(x&(-x));
     33     }
     34   return s;
     35 }
     36 int query2(int x)
     37 {
     38   int s=0;
     39   while (x<=n)
     40     {
     41       s+=c2[x];
     42       x+=(x&(-x));
     43     }
     44   return s;
     45 }
     46 void update(int x,int &y,int l,int r,int k)
     47 {
     48   y=++tot;
     49   ch[y][0]=ch[x][0];ch[y][1]=ch[x][1];
     50   sum[y]=sum[x]+1;
     51   if (l==r) return;
     52   int mid=(l+r)/2;
     53   if (k<=mid) update(ch[x][0],ch[y][0],l,mid,k);
     54   else update(ch[x][1],ch[y][1],mid+1,r,k);
     55 }
     56 int getsum(int x,int y,int l,int r,int L,int R)
     57 {
     58   if (L>R) return 0;
     59   if (l>=L&&r<=R)
     60     {
     61       return sum[y]-sum[x];
     62     }
     63   int mid=(l+r)/2,s=0;
     64   if (L<=mid) s+=getsum(ch[x][0],ch[y][0],l,mid,L,R);
     65   if (R>mid) s+=getsum(ch[x][1],ch[y][1],mid+1,r,L,R);
     66   return s;
     67 }
     68 int main()
     69 {int i,j,l,r,x;
     70   cin>>n;
     71   for (i=1;i<=n;i++)
     72     {
     73       scanf("%d",&a[i]);
     74       d[i]=a[i];
     75     }
     76   sort(d+1,d+n+1);
     77   siz=unique(d+1,d+n+1)-d-1;
     78   for (i=1;i<=n;i++)
     79     a[i]=lower_bound(d+1,d+siz+1,a[i])-d;
     80   lim=sqrt(n);
     81   for (i=1;i<=n;i+=lim)
     82     {
     83       bl[++cnt]=i;br[cnt]=min(n,i+lim-1);
     84       for (j=bl[cnt];j<=br[cnt];j++)
     85     pos[j]=cnt;
     86     }
     87   for (i=1;i<=cnt;i++)
     88     {
     89       add1(a[br[i]],1);
     90       for (j=br[i]-1;j>=1;j--)
     91     {
     92       f[j][i]=f[j+1][i]+query1(a[j]-1);
     93       add1(a[j],1);
     94     }
     95       for (j=br[i];j>=1;j--)
     96     add1(a[j],-1);
     97     }
     98   for (i=1;i<=n;i++)
     99     {
    100       update(root[i-1],root[i],1,n,a[i]);
    101     }
    102   cin>>m;
    103   ans=0;
    104   for (i=1;i<=m;i++)
    105     {
    106       scanf("%d%d",&l,&r);
    107       l^=ans;r^=ans;
    108       ans=0;
    109       if (l>r)
    110     {printf("0
    ");continue;}
    111       if (pos[l]==pos[r])
    112     {
    113       for (j=l;j<=r;j++)
    114         ans+=query2(a[j]+1),add2(a[j],1);
    115       for (j=l;j<=r;j++)
    116         add2(a[j],-1);
    117     }
    118       else
    119     {
    120       if (br[pos[r]]==r)
    121         ans=f[l][pos[r]];
    122       else
    123         {
    124          ans=f[l][pos[r]-1];x=br[pos[r]-1];
    125          if (x)
    126            {
    127          for (j=x+1;j<=r;j++)
    128            {
    129              ans+=getsum(root[l-1],root[x],1,n,a[j]+1,n);
    130            }
    131          for (j=x+1;j<=r;j++)
    132             ans+=query2(a[j]+1),add2(a[j],1);
    133          for (j=x+1;j<=r;j++)
    134             add2(a[j],-1);
    135            }
    136         }
    137     }
    138       printf("%d
    ",ans);
    139     }
    140 }
  • 相关阅读:
    Linux下tomcat中多项目配置druid报错的问题
    chrome实用快捷键速记
    count 与 group by
    H5相机上传图片压缩
    图片通过转base64上传
    内网之间访问
    composer 加载第三方类库
    访问一个项目生成两个session文件原因
    arttemplate.js 如何不直接输出html代码
    Tomcat 支持多少并发量
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8256958.html
Copyright © 2011-2022 走看看