zoukankan      html  css  js  c++  java
  • 【bzoj3809】Gty的二逼妹子序列

    【bzoj3809】Gty的二逼妹子序列
    2014年12月21日1,03512
    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。
    建议使用输入/输出优化。

    之前一直以为莫对就是分块,

    然后这道分块和莫对结合,让我看出两种不同:莫对是用分块去做,但是是对离线询问的一种优化,

    得到答案的过程还是要自己的转移路线的。

    这一我们对颜色分块,询问一个区间颜色的种类的话,就是O(sqrt(n))了,然后又M次询问,询问时O(sqrt(n)),莫对是n^1.5;

    所以复杂度是O((M+N)*sqr(n); 

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<math.h>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<vector>
     8 #include<stdlib.h>
     9 
    10 #define inf 0x3f3f3f
    11 #define N 1234567
    12 
    13 using namespace std;
    14 
    15 int a[N],pos[N],block,b[N];
    16 int n,m,k;
    17 int f[N];
    18 struct node
    19 {
    20     int l,r,id,ans,a,b;
    21 }q[N];
    22 
    23 int cmp(node a,node b)
    24 {
    25     if (pos[a.l]==pos[b.l]) return a.r<b.r;
    26     return pos[a.l]<pos[b.l];
    27 }
    28 
    29 
    30 int cmpid(node a,node b)
    31 {
    32     return a.id<b.id;
    33 }
    34 int cn[N],B[N];
    35 void add(int c,int val)
    36 {
    37     if (!cn[c]) ++B[pos[c]];
    38     cn[c]+=val;
    39     if (!cn[c]) --B[pos[c]];
    40 }
    41 
    42 int query(int x,int y)
    43 {
    44     int ans=0;
    45     if (pos[x]==pos[y]){
    46     for(int i=x;i<=y;i++)
    47     if (cn[i]) ans++;
    48     }
    49     else
    50     {
    51         for (int i=pos[x]*block;i>=x;i--)
    52         if (cn[i]) ans++;
    53         for (int i=(pos[y]-1)*block+1;i<=y;i++)
    54         if (cn[i]) ans++;
    55         for (int i=pos[x]+1;i<pos[y];i++)
    56         ans+=B[i];
    57     }
    58     return ans;
    59 }
    60 void solve()
    61 {
    62     int l=1,r=0;
    63     int ans=0;
    64     for (int i=1;i<=m;i++)
    65     {
    66         while (l<q[i].l)
    67         add(a[l],-1),l++;//减去a[l]产生的影响
    68         while (l>q[i].l)
    69         l--,add(a[l],1);//加上a[l]的infection
    70         while (r>q[i].r)
    71         add(a[r],-1),r--;//d the infection of a[r] ,note r-l
    72         while (r<q[i].r)
    73         r++,add(a[r],1);//add the infection of a[r]
    74 
    75         q[i].ans=query(q[i].a,q[i].b);
    76     }
    77 }
    78 
    79 int main()
    80 {
    81     scanf("%d%d",&n,&m);
    82     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    83     
    84     block=sqrt(n);
    85 
    86     for (int i=1;i<=n;i++)
    87     pos[i]=(i-1)/block+1;
    88 
    89     for (int i=1;i<=m;i++)
    90     scanf("%d%d%d%d",&q[i].l,&q[i].r,&q[i].a,&q[i].b),q[i].id=i;
    91 
    92     sort(q+1,q+m+1,cmp);
    93     solve();
    94     sort(q+1,q+m+1,cmpid);
    95     for (int i=1;i<=m;i++)
    96     printf("%d ",q[i].ans);

    97 } 

  • 相关阅读:
    在Magento产品分类页面创建推荐产品
    任意两个时间之间的星期几的次数纵.sql
    SQL 日期格式化处理.sql
    系统应用程序域
    在ubuntu12.04中,apc_cache_find()
    buildertheory.cs
    复杂年月处理.sql
    CurrentAccounts.cs
    CLR和Windows加载器
    应用程序域
  • 原文地址:https://www.cnblogs.com/forgot93/p/4784333.html
Copyright © 2011-2022 走看看