zoukankan      html  css  js  c++  java
  • BZOJ3744 Gty的妹子序列(分块+树状数组)

    题意

    询问区间内逆序对数  强制在线

    1<=n<=50000 1<=m<=50000

    题解

    两个预处理f[i][j]为块i到j的逆序对数,s[i][j]前i块≤j的有多少个
    边角余料用个树状数组就行了

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=50100;
     8 int n,Block,a[N],b[N],block[N],R[500],L[500],f[500][500],tr[500][N],m,ans;
     9 int lowbit(int x){
    10     return x&-x;
    11 }
    12 void add(int id,int x,int w){
    13     for(int i=x;i<=n;i+=lowbit(i)){
    14         tr[id][i]+=w;
    15     }
    16 }
    17 int getsum(int id,int x){
    18     int tmp=0;
    19     for(int i=x;i;i-=lowbit(i)){
    20         tmp+=tr[id][i];
    21     }
    22     return tmp;
    23 }
    24 int main(){
    25     scanf("%d",&n);
    26     Block=sqrt(n);
    27     for(int i=1;i<=n;i++){
    28         scanf("%d",&a[i]);
    29         b[i]=a[i];
    30         block[i]=(i-1)/Block+1;
    31         if(!L[block[i]])L[block[i]]=i;
    32         R[block[i]]=i;
    33     }
    34     sort(b,b+1+n);
    35     int tot=unique(b+1,b+1+n)-b-1;
    36     for(int i=1;i<=n;i++){
    37         a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
    38     }
    39     for(int i=1;i<=block[n];i++){
    40         for(int j=L[i];j<=n;j++){
    41             add(i,a[j],1);
    42         } 
    43     }
    44     for(int i=1;i<=block[n];i++){
    45         int tot=0;
    46         for(int j=L[i];j<=n;j++){
    47             add(0,a[j],1);
    48             tot+=getsum(0,n)-getsum(0,a[j]);
    49             f[i][block[j]]=tot;
    50         }
    51         for(int j=L[i];j<=n;j++){
    52             add(0,a[j],-1);
    53         }
    54     }
    55     scanf("%d",&m);
    56     while(m--){
    57         int l,r;
    58         scanf("%d%d",&l,&r);
    59         l=l^ans;r=r^ans;
    60         if(l>r)swap(l,r);
    61         if(l==0||r==0||l>n||r>n)continue;
    62         if(block[l]+1>=block[r]){
    63             ans=0;
    64             for(int i=l;i<=r;i++){
    65                 add(0,a[i],1);
    66                 ans+=getsum(0,n)-getsum(0,a[i]);
    67             }
    68             for(int i=l;i<=r;i++){
    69                 add(0,a[i],-1);
    70             }
    71         } 
    72         else{
    73             ans=f[block[l]+1][block[r]-1];
    74             int size=L[block[r]]-R[block[l]]-1;
    75         //    cout<<ans<<" "<<size<<"sdjksd"<<endl;
    76             for(int i=l;i<=R[block[l]];i++){
    77                 ans+=getsum(block[l]+1,a[i]-1)-getsum(block[r],a[i]-1);
    78                 add(0,a[i],1);
    79                 ans+=getsum(0,n)-getsum(0,a[i]);
    80             }
    81             for(int i=L[block[r]];i<=r;i++){
    82                 ans+=size-(getsum(block[l]+1,a[i])-getsum(block[r],a[i]));
    83                 add(0,a[i],1);
    84                 ans+=getsum(0,n)-getsum(0,a[i]);
    85             }
    86             for(int i=l;i<=R[block[l]];i++){
    87                 add(0,a[i],-1);
    88             }
    89             for(int i=L[block[r]];i<=r;i++){
    90                 add(0,a[i],-1);
    91             }        
    92         }
    93         printf("%d
    ",ans);
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    【设置图片主体部分居中】
    高效数据查询设计思想
    SpringBoot中的classpath
    mysql优化口诀
    windows安装kafka
    windows安装rabbitmq
    使用Charles在移动端抓包
    07 哨兵机制:主库挂了,如何不间断服务
    操作系统(一)操作系统历史:从标准函数库到云计算
    06 数据同步:主从库如何实现数据一致
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9495555.html
Copyright © 2011-2022 走看看