zoukankan      html  css  js  c++  java
  • bzoj 3809 Gty的二逼妹子序列(莫队算法,块状链表)

    【题意】

        回答若干个询问,(l,r,a,b):区间[l,r]内权值在[a,b]的数有多少[种]。

    【思路】

        考虑使用块状链表实现莫队算法中的插入与删除。

        因为权值处于1..n之间,所以我们可以建一个基于权值的块状链表,每个块维护一个区间信息sum,表示权值在该块的数的种数。

        这样插入与删除只需要O(1)的时间,查询需要O(sqrt(n))的时间,总的时间复杂度为O(n^1.5+qn^0.5)

    【代码】

     1 #include<set>
     2 #include<cmath>
     3 #include<queue>
     4 #include<vector>
     5 #include<cstdio>
     6 #include<cstring>
     7 #include<iostream>
     8 #include<algorithm>
     9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
    10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
    11 using namespace std;
    12 
    13 typedef long long ll;
    14 const int N = 3e5+10;
    15 
    16 ll read() {
    17     char c=getchar();
    18     ll f=1,x=0;
    19     while(!isdigit(c)) {
    20         if(c=='-') f=-1; c=getchar();
    21     }
    22     while(isdigit(c))
    23         x=x*10+c-'0',c=getchar();
    24     return x*f;
    25 }
    26 
    27 int n,m,B;
    28 int pos[N],sum[N],cnt[N],a[N],ans[N];
    29 
    30 struct Node 
    31 {
    32     int id,l,r,a,b;
    33     bool operator < (const Node& rhs) const 
    34     {
    35         return pos[l]<pos[rhs.l]||(pos[l]==pos[rhs.l]&&r<rhs.r);
    36     }
    37 } q[N];
    38 
    39 void upd(int x,int v)
    40 {
    41     cnt[x]+=v;
    42     if(v==1&&cnt[x]==1) sum[pos[x]]++;
    43     if(v==-1&&cnt[x]==0) sum[pos[x]]--; 
    44 }
    45 int query(int l,int r)
    46 {
    47     int bl=pos[l],br=pos[r];
    48     int ans=0;
    49     if(bl==br)
    50     {
    51         FOR(i,l,r) ans+=cnt[i]>0;
    52         return ans;
    53     }
    54     FOR(i,bl+1,br-1) ans+=sum[i];
    55     bl=B*bl;
    56     br=B*(br-1)+1;
    57     FOR(i,l,bl) ans+=cnt[i]>0;
    58     FOR(i,br,r) ans+=cnt[i]>0;
    59     return ans;
    60 }
    61 
    62 int main()
    63 {
    64     n=read(),m=read();
    65     FOR(i,1,n) a[i]=read();
    66     B=sqrt(n+0.5);
    67     FOR(i,1,n) pos[i]=(i-1)/B+1;
    68     FOR(i,1,m)
    69     {
    70         q[i].l=read(),q[i].r=read();
    71         q[i].a=read(),q[i].b=read();
    72         q[i].id=i;
    73     }
    74     sort(q+1,q+m+1);
    75     int l=1,r=0;
    76     FOR(i,1,m) 
    77     {
    78         while(l<q[i].l) upd(a[l++],-1);
    79         while(l>q[i].l) upd(a[--l],1);
    80         while(r<q[i].r) upd(a[++r],1);
    81         while(r>q[i].r) upd(a[r--],-1);
    82         ans[q[i].id]=query(q[i].a,q[i].b);
    83     }
    84     FOR(i,1,m)
    85         printf("%d
    ",ans[i]);
    86     return 0;
    87 }
  • 相关阅读:
    Jobs(一)前端页面
    MySQL 聚合函数与count()函数
    计算机概论 64bit和32bit的CPU的不同
    Maven如何发布项目到一个Tomcat中
    创建一个简单的Maven工程
    Maven安装与配置
    Maven整合Spring与Solr
    solr应用
    hashCode()与equals()区别
    Callable与Future
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5345365.html
Copyright © 2011-2022 走看看