zoukankan      html  css  js  c++  java
  • BZOJ 3809 Gty的二逼妹子序列

    3809: Gty的二逼妹子序列

    Time Limit: 80 Sec  Memory Limit: 28 MB
    Submit: 2195  Solved: 674
    [Submit][Status][Discuss]

    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。
    建议使用输入/输出优化。
     
     
    分块大法好啊,莫队离线然后分块查询,块大小为(int)ceil(sqrt(1.0*n))最为合适
    读入读出优化

    char buf[1<<15],*fs,*ft;
    inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
    inline int read(){
    int x=0,f=1; char ch=getc();
    while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getc();}
    while(isdigit(ch)) {x=x*10+ch-'0'; ch=getc();}
    return x*f;
    }
    void put(int x){
    if(x==0){
    putchar('0');
    putchar(' ');
    return;
    }
    if(x<0){
    putchar('-');
    x=-x;
    }
    int num=0;char ch[16];
    while(x) ch[++num]=x%10+'0',x/=10;
    while(num) putchar(ch[num--]);
    putchar(' ');
    }

    #include <bits/stdc++.h>
    using namespace std;
    char buf[1<<15],*fs,*ft;
    inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
    inline int read(){
    int x=0,f=1;  char ch=getc();
    while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getc();}
    while(isdigit(ch))  {x=x*10+ch-'0';  ch=getc();}
    return x*f;
    }
    void put(int x){
    if(x==0){
    putchar('0');
    putchar('
    ');
    return;
    }
    if(x<0){
    putchar('-');
    x=-x;
    }
    int num=0;char ch[16];
    while(x) ch[++num]=x%10+'0',x/=10;
    while(num) putchar(ch[num--]);
    putchar('
    ');
    }
    int block;
    struct node{
     int r;
     int l ;
     int a;
     int b;
     int id;
    }Q[1000010];
    int belong[100010];
    int L[100010];
    int R[100100];
    int pos[100010];
    int n;
    int Ans[1001000];
    int c[100010]={};
    int d[100010]={};
    bool mycmp(node a,node b){
     if(pos[a.l]==pos[b.l]) return a.r<b.r;
     return a.l<b.l;
    }
    inline void delate(int x){
     c[x]--;
     if(c[x]==0) d[belong[x]]--;
    }
    inline void update(int x){
     c[x]++;
     if(c[x]==1) d[belong[x]]++;
    }
    inline int query(int x,int y){
     int tmp=0;
     for(int i=belong[x]+1;i<=belong[y]-1;i++){
      tmp+=d[i];
     }
     if(belong[x]==belong[y]) {
      for(int i=x;i<=y;i++){
       if(c[i]) tmp++;
      }
      return tmp;
     }
     else{
      for(int i=x;i<=R[belong[x]];i++){
       if(c[i]) tmp++;
      }
      for(int i=L[belong[y]];i<=y;i++){
       if(c[i]) tmp++;
      }
     }
     return tmp;
    }
    void build(){
     block=(int)ceil(sqrt(1.0*n));
     int num=n/block;
     if(n%block) num++;
     for(int i=1;i<=num;i++){
      L[i]=(i-1)*block+1;R[i]=i*block;
     }
     R[num]=n;
     for(int i=1;i<=n;i++){
      belong[i]=(i-1)/block+1;
     }
    } 
    int m;
    int a[100010];
    int main(){
     //freopen("a.in","r",stdin);
     //freopen("a.out","w",stdout);
     cin>>n>>m;
     int sz=(int)ceil(sqrt(1.0*n));
     for(int i=1;i<=n;i++){
      a[i]=read();
      pos[i]=(i-1)/sz;
     }
     for(int i=1;i<=m;i++){
      Q[i].l=read();
      Q[i].r=read();
      Q[i].a=read();
      Q[i].b=read();
      Q[i].id=i;
     }
     sort(Q+1,Q+m+1,mycmp);
     build();
     int L=1;
     int R=0;
     for(int i=1;i<=m;i++){
      int id=Q[i].id;
      while(L<Q[i].l) {delate(a[L]);L++;}
      while(L>Q[i].l) {L--;update(a[L]);}
      while(R<Q[i].r) {R++;update(a[R]);}
      while(R>Q[i].r) {delate(a[R]);R--;}
      Ans[id]=query(Q[i].a,Q[i].b);
     }
     for(int i=1;i<=m;i++){
      put(Ans[i]);
     }
     return 0;
    }
    

      

  • 相关阅读:
    如何在java类中读取Properties配置文件
    常用网址 转
    我的读书计划
    制作一个半透明遮罩层的库——TipView
    RxJava 中的 subscribeOn 和 observeOn 的区别
    一个操作SQLite数据库的例子
    Java ThreadLocal
    3. 请求与响应
    Java的Volatile关键字
    排序
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/8092571.html
Copyright © 2011-2022 走看看