zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    LeetCode 1275. 找出井字棋的获胜者 Find Winner on a Tic Tac Toe Game
    LeetCode 307. 区域和检索
    LeetCode 1271 十六进制魔术数字 Hexspeak
    秋实大哥与花 线段树模板
    AcWing 835. Trie字符串统计
    Leetcode 216. 组合总和 III
    Mybatis 示例之 复杂(complex)属性(property)
    Mybatis 示例之 复杂(complex)属性(property)
    Mybatis 高级结果映射 ResultMap Association Collection
    Mybatis 高级结果映射 ResultMap Association Collection
  • 原文地址:https://www.cnblogs.com/LQ-double/p/5978812.html
Copyright © 2011-2022 走看看