• bzoj 3809: Gty的二逼妹子序列


    3809: Gty的二逼妹子序列

    Time Limit: 80 Sec  Memory Limit: 28 MB

    Description

    Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题。
     
    对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数。
     
    为了方便,我们规定妹子们的美丽度全都在[1,n]中。
     
    给定一个长度为n(1<=n<=100000)的正整数序列s(1<=si<=n),对于m(1<=m<=1000000)次询问“l,r,a,b”,每次输出sl...sr中,权值∈[a,b]的权值的种类数。

    Input

    第一行包括两个整数n,m(1<=n<=100000,1<=m<=1000000),表示数列s中的元素数和询问数。
     
    第二行包括n个整数s1...sn(1<=si<=n)。
     
    接下来m行,每行包括4个整数l,r,a,b(1<=l<=r<=n,1<=a<=b<=n),意义见题目描述。
     
    保证涉及的所有数在C++的int内。
     
    保证输入合法。

    Output

    对每个询问,单独输出一行,表示sl...sr中权值∈[a,b]的权值的种类数。

    Sample Input

    10 10
    4 4 5 1 4 1 5 1 2 1
    5 9 1 2
    3 4 7 9
    4 4 2 5
    2 3 4 7
    5 10 4 4
    3 9 1 1
    1 4 5 9
    8 9 3 3
    2 2 1 6
    8 9 1 4

    Sample Output

    2
    0
    0
    2
    1
    1
    1
    0
    1
    2

    HINT

    样例的部分解释:

     

    5 9 1 2

    子序列为4 1 5 1 2

    在[1,2]里的权值有1,1,2,有2种,因此答案为2。

     

    3 4 7 9

    子序列为5 1

    在[7,9]里的权值有5,有1种,因此答案为1。

     

    4 4 2 5

    子序列为1

    没有权值在[2,5]中的,因此答案为0。

     

    2 3 4 7

    子序列为4 5

    权值在[4,7]中的有4,5,因此答案为2。

     

    建议使用输入/输出优化。

     Solution:

      这里对于数字进行分块,然后我们将询问根据左端点排序后,就可以用莫队在很可观的的时间复杂度内算出答案了

     本蒟蒻打出的第一个莫队(+分块),how amazing.
     算法的魅力阿 以及就是不写读入优化,你咬我呀
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn=100020;
     8 const int maxm=1000020;
     9 struct haha
    10 {
    11     int l,r,a,b,pos;
    12 }q[maxm];
    13 int a[maxn],ans[maxm],bel[maxn],c[maxn],sum[maxn],n,m;
    14 bool cmp(const haha lu,const haha d) {return bel[lu.l] == bel[d.l] ? lu.r < d.r : lu.l < d.l;}
    15 void inti()
    16 {
    17     scanf("%d%d",&n,&m);
    18     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    19     for(int i=1;i<=m;i++) scanf("%d%d%d%d",&q[i].l,&q[i].r,&q[i].a,&q[i].b),q[i].pos=i;
    20     int block;
    21     block=sqrt(n+0.5);
    22     for(int i=1;i<=n;i++) bel[i]=(i-1)/block+1;
    23 }
    24 int query(int a,int b)
    25 {
    26     int l=bel[a],r=bel[b],tot=0;
    27     if(l==r)
    28     {
    29         for(int i=a;i<=b;i++)
    30         if(c[i]>0) tot++;
    31         return tot;
    32     }
    33     for(int i=a;bel[i]==bel[a];i++)
    34      if(c[i]>0) tot++;
    35     for(int i=b;bel[i]==bel[b];i--)
    36      if(c[i]>0) tot++;
    37     for(int i=bel[a]+1;i<bel[b];i++)
    38     tot+=sum[i];
    39     return tot;
    40 }
    41 void updata(int x,int flag)
    42 {
    43     c[x]+=flag;
    44     if(flag==-1&&c[x]==0) sum[bel[x]]--;
    45     if(flag==1&&c[x]==1) sum[bel[x]]++;
    46 }
    47 void work()
    48 {
    49     sort(q+1,q+m+1,cmp);
    50     int l,r,ll,rr; l=1;r=0;
    51     for(int i=1;i<=m;i++)
    52     {
    53         ll=q[i].l;rr=q[i].r;
    54         while(l<ll) updata(a[l++],-1);
    55         while(l>ll) updata(a[--l],1);
    56         while(r<rr) updata(a[++r],1);
    57         while(r>rr) updata(a[r--],-1);
    58         ans[q[i].pos]=query(q[i].a,q[i].b);
    59     }
    60 }
    61 int main()
    62 {
    63     inti();
    64     work();
    65     for(int i=1;i<=m;i++)
    66     printf("%d
    ",ans[i]);
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    Spring Cloud 接口契约测试
    看我玩弄千万日志于股掌
    从哲学层面浅谈计算机学习方法论
    一切互联网优势都是效率优势,一切竞争最终都是效率之争
    Arduino--蜂鸣器
    Arduino--光感应模块--模拟输入
    Arduino---按钮
    Arduino--PWM引脚
    Arduino专用绘图软件Fritzing
    点亮LED灯
  • 原文地址:https://www.cnblogs.com/LQ-double/p/5978812.html
Copyright © 2020-2023  润新知