zoukankan      html  css  js  c++  java
  • BZOJ

    题目链接

    静态区间逆序对数查询,这道题用线段树貌似不好做,可以把区间分成$sqrt n$块,预处理出两个数组:$sum[i][j]$和$inv[i][j]$,$sum[i][j]$表示前i个块中小于等于j的数的个数,$inv[i][j]$表示第i块与第j块之间的逆序对数,递推搞一下就行。查询的时候中间的部分直接查询,两边多出来的部分暴力计算贡献即可。总复杂度$O(nsqrt nlogn)$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=5e4+10,sqrtN=226,inf=0x3f3f3f3f;
     5 int a[N],b[N],c[N],n2,in[N],L[sqrtN],R[sqrtN],n,m,sqrtn,nb;
     6 int sum[sqrtN][N],inv[sqrtN][sqrtN];
     7 void add(int u,int x) {for(; u<=n2; u+=u&-u)c[u]+=x;}
     8 int get(int u) {int ret=0; for(; u; u-=u&-u)ret+=c[u]; return ret;}
     9 int main() {
    10     scanf("%d",&n),sqrtn=sqrt(n+0.5);
    11     for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
    12     for(int i=1; i<=n; ++i)b[i-1]=a[i];
    13     sort(b,b+n),n2=unique(b,b+n)-b;
    14     for(int i=1; i<=n; ++i)a[i]=lower_bound(b,b+n2,a[i])-b+1;
    15     for(int i=1; i<=n; ++i) {nb=in[i]=i/sqrtn+1; if(!L[in[i]])L[in[i]]=i; R[in[i]]=i;}
    16     for(int i=1; i<=nb; ++i) {
    17         for(int j=L[i]; j<=R[i]; ++j)sum[i][a[j]]++;
    18         for(int j=2; j<=n; ++j)sum[i][j]+=sum[i][j-1];
    19         for(int j=1; j<=n; ++j)sum[i][j]+=sum[i-1][j];
    20     }
    21     for(int i=1; i<=nb; ++i) {
    22         for(int j=R[i]; j>=L[i]; --j)inv[i][i]+=get(a[j]-1),add(a[j],1);
    23         for(int j=R[i]; j>=L[i]; --j)add(a[j],-1);
    24     }
    25     for(int i=1; i<=nb; ++i)
    26         for(int j=i+1; j<=nb; ++j) {
    27             for(int k=L[j]; k<=R[j]; ++k)inv[i][j]+=(R[j-1]-L[i]+1)-(sum[j-1][a[k]]-sum[i-1][a[k]]);
    28             inv[i][j]+=inv[i][j-1]+inv[j][j];
    29         }
    30     scanf("%d",&m);
    31     for(int ans=0; m--;) {
    32         int l,r;
    33         scanf("%d%d",&l,&r),l^=ans,r^=ans,ans=0;
    34         if(in[l]==in[r]) {
    35             for(int i=r; i>=l; --i)ans+=get(a[i]-1),add(a[i],1);
    36             for(int i=r; i>=l; --i)add(a[i],-1);
    37         } else {
    38             int lb=in[l]+1,rb=in[r]-1;
    39             if(lb<=rb) {
    40                 ans+=inv[lb][rb];
    41                 for(int i=r; i>=L[in[r]]; --i)ans+=(R[rb]-L[lb]+1)-(sum[rb][a[i]]-sum[lb-1][a[i]]);
    42                 for(int i=R[in[l]]; i>=l; --i)ans+=sum[rb][a[i]-1]-sum[lb-1][a[i]-1];
    43             }
    44             for(int i=r; i>=L[in[r]]; --i)ans+=get(a[i]-1),add(a[i],1);
    45             for(int i=R[in[l]]; i>=l; --i)ans+=get(a[i]-1),add(a[i],1);
    46             for(int i=r; i>=L[in[r]]; --i)add(a[i],-1);
    47             for(int i=R[in[l]]; i>=l; --i)add(a[i],-1);
    48         }
    49         printf("%d
    ",ans);
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    趁热打铁(如何改bug)
    element el-input的autofocus失效问题解决
    为什么要将图片转为base64格式
    学习jdk1.8的Lambda和Stream
    (隐式参数)java8的方法引用之重新认识java的this关键字
    记一次惊奇面试,希望能为广大求职中的javaer提供一点经验。
    单机版ZooKeeper的安装教程
    两个对象值转换的方法(BeanUtils.copyProperties与JSONObject.parseObject对比)
    SpringBoot监控管理之Admin监管使用
    安利一个十分实用的IDEA插件--RestfulToolkit
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10700744.html
Copyright © 2011-2022 走看看