• bzoj3809: Gty的二逼妹子序列


    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(M√N log N),会TLE
    正确的姿势是对权值分块,这样使得每次查询复杂度变为O(√n),而修改的复杂度变为O(1)
    这样总复杂度为O(M√N)
    code:
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define maxn 100005
     7 using namespace std;
     8 char ch;
     9 int n,m,siz,s[maxn],cnt[maxn],sum[400],pos[maxn],ans[maxn*10];
    10 bool ok;
    11 void read(int &x){
    12     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    13     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    14     if (ok) x=-x;
    15 }
    16 struct Query{
    17     int l,r,a,b,id;
    18     void init(int i){read(l),read(r),read(a),read(b),id=i;}
    19 }list[maxn*10];
    20 bool cmp(Query a,Query b){
    21     if (pos[a.l]!=pos[b.l]) return pos[a.l]<pos[b.l];
    22     return pos[a.r]<pos[b.r];    
    23 }
    24 void add(int col){
    25     cnt[col]++;
    26     if (cnt[col]==1) sum[pos[col]]++;
    27 }
    28 void del(int col){
    29     cnt[col]--;
    30     if (!cnt[col]) sum[pos[col]]--;
    31 }
    32 int query(int l,int r){
    33     int ans=0;
    34     for (int i=pos[l]+1;i<pos[r];i++) ans+=sum[i];
    35     if (pos[l]!=pos[r]){
    36         for (int i=l;pos[i]==pos[l];i++) if (cnt[i]) ans++;
    37         for (int i=r;pos[i]==pos[r];i--) if (cnt[i]) ans++;
    38     }
    39     else for (int i=l;i<=r;i++) if (cnt[i]) ans++;
    40     return ans;
    41 }
    42 void work(){
    43     int l=1,r=0;
    44     for (int i=1;i<=m;i++){
    45         for (;r<list[i].r;r++) add(s[r+1]);
    46         for (;r>list[i].r;r--) del(s[r]);
    47         for (;l<list[i].l;l++) del(s[l]);
    48         for (;l>list[i].l;l--) add(s[l-1]);
    49         ans[list[i].id]=query(list[i].a,list[i].b);
    50     }
    51 }
    52 int len;
    53 char ss[30];
    54 void write(int v){
    55     if (!v) putchar('0');
    56     for (len=0;v;v/=10) ss[++len]=(v%10)+'0';
    57     for (;len;len--) putchar(ss[len]);
    58     putchar('
    ');
    59 }
    60 int main(){
    61     read(n),read(m),siz=(int)sqrt(n);
    62     for (int i=1;i<=n;i++) read(s[i]);
    63     for (int i=1;i<=m;i++) list[i].init(i);
    64     for (int i=1;i<=n;i++) pos[i]=i/siz;
    65     sort(list+1,list+m+1,cmp);
    66     work();
    67     for (int i=1;i<=m;i++) write(ans[i]);
    68     return 0;
    69 }
  • 相关阅读:
    音乐播放器
    滚动视图、定时器、分页控件的综合使用
    简易拼图
    IOS开发复习笔记(1)-OC基础知识
    64位matlab mex64位编译器解决方案
    LibSvm添加到Matlab
    code first 数据库无损迁移
    asp.net mvc4连接mysql
    自定义控件引用时候尺寸发生变化
    jquery 操作动态添加的元素
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/4708397.html
Copyright © 2020-2023  润新知