zoukankan      html  css  js  c++  java
  • bzoj3744 Gty的妹子序列

    我是萌萌的传送门

    感觉这题还是不错的……虽然其实算是比较水的题= =

    首先分块,令f[i][j]表示第i块到第j块的逆序对数,询问的时候直接计算不完整块与完整块以及不完整块之间的逆序对。

    不完整块之间的逆序对直接树状数组暴力求,至于不完整块和完整块的逆序对,我是令s[i]表示前i块的权值前缀和,这样单次查询O(1),可以减小一点常数,代价是空间稍微费了点……

    预处理O(nsqrt(n)logn),单次查询O(sqrt(n)logn),空间O(nsqrt(n)),好吧我懒得算如何调节块大小来降低复杂度了,于是就随便找了个233当的块大小= =

    细节并不多,然而因为各种脑残错误调了半天才敢交,又因为没看见要离散化和没加强制在线RE两次,真是废了……

     1 /**************************************************************
     2     Problem: 3744
     3     User: hzoier
     4     Language: C++
     5     Result: Accepted
     6     Time:9688 ms
     7     Memory:49700 kb
     8 ****************************************************************/
     9  
    10 #include<cstdio>
    11 #include<cstring>
    12 #include<algorithm>
    13 using namespace std;
    14 const int maxn=50010,B=233,maxb=245;
    15 void add(int,int);
    16 int query(int);
    17 int a[maxn],b[maxn],id[maxn],L[maxb]={0},R[maxb]={0},cntb,f[maxb][maxb]={{0}},s[maxb][maxn]={{0}},c[maxn]={0};
    18 int n,m,l,r,lb,rb,ans=0;
    19 int main(){
    20     scanf("%d",&n);
    21     for(int i=1;i<=n;i++){
    22         scanf("%d",&a[i]);
    23         cntb=id[i]=(i-1)/B+1;
    24         if(!L[id[i]])L[id[i]]=i;
    25         R[id[i]]=i;
    26     }
    27     copy(a+1,a+n+1,b+1);
    28     sort(b+1,b+n+1);
    29     for(int i=1;i<=n;i++)s[id[i]][a[i]=lower_bound(b+1,b+n+1,a[i])-b]++;
    30     for(int i=1;i<=cntb;i++){
    31         for(int j=1;j<=n;j++)s[i][j]+=s[i-1][j];
    32         for(int j=i;j<=cntb;j++){
    33             for(int k=L[j];k<=R[j];k++){
    34                 f[i][j]+=query(a[k]+1);
    35                 add(a[k],1);
    36             }
    37             f[i][j]+=f[i][j-1];
    38         }
    39         memset(c,0,sizeof(c));
    40     }
    41     for(int i=1;i<=cntb;i++)for(int j=1;j<=n;j++)s[i][j]+=s[i][j-1];
    42     scanf("%d",&m);
    43     while(m--){
    44         scanf("%d%d",&l,&r);
    45         l^=ans;r^=ans;
    46         if(id[l]>=id[r]-1){
    47             ans=0;
    48             for(int i=l;i<=r;i++){
    49                 ans+=query(a[i]+1);
    50                 add(a[i],1);
    51             }
    52             for(int i=l;i<=r;i++)add(a[i],-1);
    53         }
    54         else{
    55             lb=id[l]+1;rb=id[r]-1;
    56             ans=f[lb][rb];
    57             for(int i=l;i<L[lb];i++){
    58                 ans+=query(a[i]+1)+s[rb][a[i]-1]-s[lb-1][a[i]-1];
    59                 add(a[i],1);
    60             }
    61             for(int i=R[rb]+1;i<=r;i++){
    62                 ans+=query(a[i]+1)+(s[rb][n]-s[rb][a[i]])-(s[lb-1][n]-s[lb-1][a[i]]);
    63                 add(a[i],1);
    64             }
    65             for(int i=l;i<L[lb];i++)add(a[i],-1);
    66             for(int i=R[rb]+1;i<=r;i++)add(a[i],-1);
    67         }
    68         printf("%d
    ",ans);
    69     }
    70     return 0;
    71 }
    72 void add(int x,int d){
    73     while(x){
    74         c[x]+=d;
    75         x&=x-1;
    76     }
    77 }
    78 int query(int x){
    79     int ans=0;
    80     while(x<=n){
    81         ans+=c[x];
    82         x+=x&-x;
    83     }
    84     return ans;
    85 }
    View Code
  • 相关阅读:
    成为数据科学家并不难
    大数据分析的众包平台—Kaggle
    如何写一份好的数据分析报告
    配置java环境时,java的path地址放在其他地址的前面还是后面?
    js:随记
    JS:JSP Servlet
    [swustoj 1088] 德州扑克
    [swustoj 1092] 二分查找的最大次数
    [swustoj 371] 回文数
    [swustoj 1097] 2014
  • 原文地址:https://www.cnblogs.com/hzoier/p/6238130.html
Copyright © 2011-2022 走看看