• BZOJ3289 Mato的文件管理(莫队算法+树状数组)


    题目是区间逆序数查询。

    莫队算法。。左或右区间向左或右延伸时加或减这个区间小于或大于新数的数的个数,这个个数用树状数组来统计,我用线段树超时了。询问个数和数字个数都记为n,数字范围不确定所以离散化,这样时间复杂度就是$O(n^{frac32}log{n})$

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 using namespace std;
     6 #define MAXN 55555
     7 int block;
     8 struct Query{
     9     int i,l,r;
    10     bool operator<(const Query &q)const{
    11         if(l/block==q.l/block) return r<q.r;
    12         return l/block<q.l/block;
    13     }
    14 }que[MAXN];
    15 
    16 int bit[MAXN],N;
    17 inline int lowbit(int x){
    18     return x&(-x);
    19 }
    20 void update(int x,int k){
    21     while(x<=N){
    22         bit[x]+=k;
    23         x+=lowbit(x);
    24     }
    25 }
    26 int query(int x){
    27     if(x<=0) return 0;
    28     int res=0;
    29     while(x){
    30         res+=bit[x];
    31         x-=lowbit(x);
    32     }
    33     return res;
    34 }
    35 
    36 int b[MAXN],bn,res,tot;
    37 void insertR(int i){
    38     i=lower_bound(b+1,b+1+bn,i)-b;
    39     res+=tot-query(i);
    40     update(i,1);
    41     ++tot;
    42 }
    43 void removeR(int i){
    44     i=lower_bound(b+1,b+1+bn,i)-b;
    45     res-=tot-query(i);
    46     update(i,-1);
    47     --tot;
    48 }
    49 void insertL(int i){
    50     i=lower_bound(b+1,b+1+bn,i)-b;
    51     res+=query(i-1);
    52     update(i,1);
    53     ++tot;
    54 }
    55 void removeL(int i){
    56     i=lower_bound(b+1,b+1+bn,i)-b;
    57     res-=query(i-1);
    58     update(i,-1);
    59     --tot;
    60 }
    61 int a[MAXN],ans[MAXN];
    62 int main(){
    63     int n,m;
    64     scanf("%d",&n);
    65     block=(int)sqrt(n);
    66     for(int i=1; i<=n; ++i){
    67         scanf("%d",&a[i]);
    68         b[i]=a[i];
    69     }
    70     sort(b+1,b+1+n);
    71     bn=unique(b+1,b+1+n)-b-1;
    72     N=bn;
    73     scanf("%d",&m);
    74     for(int i=0; i<m; ++i){
    75         que[i].i=i;
    76         scanf("%d%d",&que[i].l,&que[i].r);
    77     }
    78     sort(que,que+m);
    79     int l=1,r=1; insertR(a[1]);
    80     for(int i=0; i<m; ++i){
    81         while(l<que[i].l) removeL(a[l++]);
    82         while(l>que[i].l) insertL(a[--l]);
    83         while(r>que[i].r) removeR(a[r--]);
    84         while(r<que[i].r) insertR(a[++r]);
    85         ans[que[i].i]=res;
    86     }
    87     for(int i=0; i<m; ++i){
    88         printf("%d
    ",ans[i]);
    89     }
    90     return 0;
    91 } 
  • 相关阅读:
    Java技术学习笔记:C/S 与B/S 区别
    Java开发面试题总结(八)
    Java技术笔记:数据库的性能优化
    零基础学习Python可以学会吗?你有哪些方法?
    java培训学习路线图之SpringBoot多模块开发学习
    计算机专业选Java和Python哪个前景好点?
    bzoj2152 聪聪可可
    bzoj1468 Tree
    bzoj2879 [Noi2012]美食节
    bzoj2208 [Jsoi2010]连通数
  • 原文地址:https://www.cnblogs.com/WABoss/p/5253129.html
Copyright © 2020-2023  润新知